4

[我開始之前,我試圖尋找相關的問題,因爲我沒有發現,我在這裏問一個問題]的Java多線程:行爲當線程對象的引用計數爲零

我學習Java和以下場景打我的頭:

class MyThread extends Thread { 
    void run(){ 
     //a heavy function 
    } 
} 

現在在主線程中,我調用這個主題爲:

public static void main(...){ 
    new MyThread().start(); 
    System.gc(); //just a request.. 
    //end of main thread too. 
    //Reference to that MyThread object is now zero. 
} 

我跑的代碼。看來線程還活着。程序結束時全部線程退出。

我的問題:

  • 當引用計數爲零,不會對線程GC資格?如果它真的符合條件,垃圾收集的行爲是什麼?線程是否會被終止?
  • 我知道這是一件壞事,但是它的定義是沒有otherThread.join()main()

我有我自己的一些解釋(但我不知道我是多麼正確的 - 因此,我在這裏發了一個帖子):只要

  • JVM maitains到線程的引用它是有效。所以ref ref永遠不會真的爲零。
  • 執行函數有一個隱含的this引用,所以ref計數再次不爲零。

我在上面的任何解釋中正確嗎?或者還有其他解釋嗎?

感謝和問候:)

回答

13

每個正在運行的線程構成GC的根。從一個根到達的任何對象都不適用於GC,並且該線程具有對java.lang.Thread實例的線程本地引用(由Thread.currentThread()返回)。所以不行,你的線程直到它結束運行纔會被GCed,因爲Thread實例可以從正在運行的線程到達。

我不明白爲什麼不在產卵的線程上調用join()是一件壞事。如果你不在乎產卵線程何時結束,你不需要加入它。當最後一個非守護線程停止運行時,應用程序將停止。

另外,請注意引用的數量不是GC用來判斷對象是否符合GC的條件。如果圖形不再可用,則維護彼此引用(例如,DOM樹)的對象圖可以符合GC的條件。

+0

+1,謝謝你非常確切的回答:) – SuperSaiyan 2012-07-16 07:34:54

+1

+1 JLS沒有說JVM不會使用引用計數。 AFAIK沒有做,因爲其已知的限制。 – 2012-07-16 08:18:02

+1

我認爲第一句話是微不足道的。我們必須注意區分一個'Thread'實例和實際的執行線程。 'new Thread()'**不會創建一個線程,也不會創建一個線程,也不會讓這個實例的GC神奇地停止線程 - 不過,新文件()的GCing會刪除一個文件磁盤。正確的答案是,通過Thread.currentThread()可以訪問線程本地引用,這使得在執行底層線程時可以隨時訪問Thread實例。 – 2012-07-16 08:26:12

4

1.JVM will terminate only when all the Non-Daemon thread including the Main thread已終止。 (主線程不是main()方法)。

2。 A 線程將立即死亡,因爲它已完成運行其run()方法,但正如您將會知道的那樣,每個線程(腳趾,即執行線程)都與Thread類的實例相關聯。

所以當線程死了,它移動到死的狀態(我這裏沒有提線程池),但是這是與線程關聯Thread類的對象仍然存在,但已經永久失去了線索。

4.但是有一個很高的機會,你的線程仍然只運行主要方法已經完成。

5.調用join()並不壞,但應謹慎使用。

+0

+1,非常感謝您的回答:) – SuperSaiyan 2012-07-16 07:36:41

+0

u r welcome .............. – 2012-07-16 07:37:25

+0

每個線程*都是Thread類的一個實例。 '與線程相關的對象'和'永久失去線程'是毫無意義的。 – EJP 2012-07-16 10:51:42

2

當引用計數爲零時,是否線程有資格使用GC?

編號線程在終止時變爲符合GC條件沒有引用。

如果確實符合條件,垃圾收集的行爲是什麼?線程是否會被終止?

參見上文。

我知道它是一件壞事,但是它在main()中沒有otherThread.join()嗎?

這並不是一件壞事,它完全定義良好:當所有非守護線程退出時,JVM將退出。

只要它處於活動狀態,JVM就保持對線程的引用。所以ref ref永遠不會真的爲零。

正確。

正在執行的函數有一個隱含的引用,所以ref計數再次不爲零。

不正確。考慮靜態方法。正在執行的函數按照定義在活動線程中執行,所以根據定義,線程是活動的,所以它不能被GC'd。你在這裏的想法是相當循環的。

+0

感謝百萬@EJP :)。我希望這個答案和其他答案一樣多。 – SuperSaiyan 2012-07-17 04:46:40