Java多线程:线程对象的引用计数变为零时的行为
[在我开始之前,我尝试搜索相关问题,因为我没有找到任何问题,我在这里问了一个问题] 我正在学习Java,下面的场景击中了我的脑袋:Java多线程:线程对象的引用计数变为零时的行为,java,multithreading,garbage-collection,reference-counting,Java,Multithreading,Garbage Collection,Reference Counting,[在我开始之前,我尝试搜索相关问题,因为我没有找到任何问题,我在这里问了一个问题] 我正在学习Java,下面的场景击中了我的脑袋: class MyThread extends Thread { void run(){ //a heavy function } } 现在在主线程中,我调用这个线程: public static void main(...){ new MyThread().start(); System.gc(); //just a
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条件?如果它确实符合条件,那么垃圾收集的行为是什么?线程是否会终止
- 我知道这是一件坏事,但是在
中没有main()
的定义是否正确otherThread.join()
- 只要线程处于活动状态,JVM就会维护对该线程的引用。所以ref计数从来都不是零
- 正在执行的函数有一个隐式的
引用,因此ref计数也不是零this
感谢和问候:)每个正在运行的线程都构成GC的根。任何可从一个根访问的对象都不符合GC的条件,并且该线程具有对
java.lang.thread
实例的线程本地引用(由thread.currentThread()
返回)。因此,不,您的线程在结束运行之前不会被GCed,因为运行的线程可以访问线程
实例
我不明白为什么不在生成的线程上调用join()
会是一件坏事。如果您不关心生成的线程何时结束,则无需加入它。当最后一个非守护进程线程停止运行时,应用程序将停止
另外,请注意,引用的数量不是GC用来判断对象是否符合GC条件的数量。如果图形不再可访问,则维护相互引用的对象的图形(例如DOM树)可以符合GC的条件。1。
JVM将仅在包括主线程在内的所有非守护进程线程终止时终止。(主线程不是Main()方法)
2。一个线程在运行完run()方法后将立即死亡,但正如您所知,每个线程(toe,即执行线程)都与Thread类的实例相关联
3.因此,当线程死亡时,它会进入死状态(我这里没有提到线程池),但是与线程关联的线程类的对象仍然存在,但已经永久性地失去了线程性。
4。但是,只有主方法完成后,线程才有很大可能仍在运行。
5.调用join()
一点也不坏,但使用时应谨慎
当引用计数为零时,线程是否符合GC条件
否。当线程终止并且没有引用时,它就有资格使用GC
如果它确实符合条件,那么垃圾收集的行为是什么?线程是否会终止
见上文
我知道这是一件坏事,但是在main()中没有otherThread.join()定义好了吗
这不是一件坏事,而且定义得很好:当所有非守护进程线程都退出时,JVM将退出
只要线程处于活动状态,JVM就会维护对它的引用。所以ref计数从来都不是零
对
执行函数有一个隐式this引用,因此ref计数也不是零
不对。考虑静态方法。根据定义,执行函数是在活动线程中执行的,因此根据定义,该线程是活动的,因此它不能是GC。您在这里的想法相当循环。+1 JLS没有说JVM不会使用引用计数。因为它已知的局限性,没有人会这样做。我认为第一句话很含糊。我们必须注意区分
线程
实例和实际执行线程new Thread()
不会创建线程,该实例的GC调用也不会神奇地停止线程,正如GC调用new File()
不会删除磁盘上的文件一样。正确的答案是,有一个线程本地引用可通过thread.currentThread()
访问,该引用使thread
实例在底层线程执行时始终可访问。@MarkoTopolnik:我编辑了我的答案以添加此信息。我使用了“running thread”,而不是“thread instance”,以明确我指的是执行线程,而不是java.lang.thread的实例。可能还不够清楚。每个线程都是thread类的一个实例。”“与线程关联的对象”和“永久失去其线程性”是没有意义的。@EJP如果您对我的回答中的这些行有问题,请向Head First Java的作者投诉,该作者是Kathy Sierra和Berth Bate
。他们可能是你真正的罪魁祸首…………非常感谢@EJP:)。我希望这个答案能像这里的其他答案一样被提升。