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