在java中,即使没有任何东西可以访问它,Thread仍会继续运行吗?

时间:2018-04-12 16:18:10

标签: java multithreading oop

所以,你有一个扩展Thread的java类ExampleThread。为了使这个例子简单,让我们说它的run()方法只是sleep()s 10秒钟,然后打印" Hello World"到屏幕。但是,它是这样创建的:

public void startThread() {
   //Create local variable
   ExampleThread example = new ExampleThread();

   example.start();

}

如果我们调用此方法然后主线程继续做其他事情,Hello World是否会被打印?大多数Java对象在没有任何东西可以引用它们的时刻就不复存在了(没有任何东西可以引用'示例',因为它是一个局部变量)。运行线程不同吗?

很抱歉,如果已经提出这个问题,我无法找到任何相关信息。

2 个答案:

答案 0 :(得分:0)

  

大多数Java对象在没有任何东西可以引用它们的时刻就不复存在了......

出于所有实际目的,这是事实,但实际上,垃圾收集器收回对象之前可能会有一段时间。

  

...没有任何东西可以引用'example',因为它是一个局部变量

你的错误。

首先,example不是Thread对象。 example变量引用Thread对象。 example调用的激活记录中存在startThread(),一旦startThread()返回,它就不再存在,但堆上存在Thread对象。并且,...

...还有另一个对你的程序中不可见的引用。

Thread对象不是线程。它只是您调用example.start()时创建的实际操作系统线程的代理。在example.start()返回之前,它已创建一个新的操作系统线程,包括该线程的堆栈。在新线程的堆栈上,在调用run()方法的下方,调用带有引用Thread对象的局部变量的私有方法。

隐藏的局部变量是在Thread返回之前保持run()不被垃圾收集的原因。 Java程序中的每个线程都有一个对其自己的Thread对象的隐藏引用。

答案 1 :(得分:0)

即使您没有持有对该线程的引用,它仍然由ThreadGroup在内部引用。否则,你认为该线程将被垃圾收集器销毁是正确的。所以这里没有特别处理,但这是一个非常明显的原因。

评论中提到的daemon属性与此无关。如果只剩下守护程序线程,Java虚拟机将关闭,但两种类型的线程都以相同的方式处理。