Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java多线程:线程对象的引用计数变为零时的行为_Java_Multithreading_Garbage Collection_Reference Counting - Fatal编程技术网

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

[在我开始之前,我尝试搜索相关问题,因为我没有找到任何问题,我在这里问了一个问题]

我正在学习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条件?如果它确实符合条件,那么垃圾收集的行为是什么?线程是否会终止
  • 我知道这是一件坏事,但是在
    main()
    中没有
    otherThread.join()
    的定义是否正确
我对自己有一些解释(但我不知道我有多正确——我在这里发帖的原因):

  • 只要线程处于活动状态,JVM就会维护对该线程的引用。所以ref计数从来都不是零
  • 正在执行的函数有一个隐式的
    this
    引用,因此ref计数也不是零
我上面的任何解释正确吗?或者还有其他的解释吗


感谢和问候:)

每个正在运行的线程都构成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:)。我希望这个答案能像这里的其他答案一样被提升。