【问题标题】:In java, does a Thread keep going even if nothing can access it?在java中,即使没有任何东西可以访问线程,它是否会继续运行?
【发布时间】:2023-03-18 17:26:01
【问题描述】:

所以,您有一个扩展 Thread 的 java 类 ExampleThread。为了简化这个例子,假设它的 run() 方法只是 sleep() 10 秒,然后在屏幕上打印“Hello World”。但是,它是这样创建的:

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

   example.start();

}

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

很抱歉,如果这已经被问过了,我找不到任何关于它的信息。

【问题讨论】:

  • 线程将继续。
  • 同时查找守护线程和非守护线程
  • 好吧,好吧 =) 你们是对的。编辑我的评论
  • [teach me] Java 中的“访问”是从几个基本位置开始计算的。这些包括静态成员变量和线程堆栈。所以线程是它自己的访问器。特别是在线程内部,您可以随时说Thread.currentThread(),为您提供访问权限。
  • @Arkadiy 这就是我喜欢这个网站的原因。我每天都在学习新东西

标签: java multithreading oop


【解决方案1】:

大多数 Java 对象在没有东西可以引用它们的那一刻就不再存在......

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

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

这是你的错误。

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

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

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

隐藏的局部变量是防止Thread 被垃圾回收,直到run() 返回之后。 Java 程序中的每个线程都有一个对其自己的Thread 对象的隐藏引用。

【讨论】:

  • 我必须尝试,但是指向你自己的隐藏变量应该被垃圾收集器视为循环,因此你的对象仍然应该被垃圾收集。还是我理解错了你的解释?
  • @Lothar,隐藏变量不是“指向你自己”。它是线程堆栈上的一个局部变量,持有对控制线程的Thread 对象的引用。线程的堆栈、Thread 对象和线程本身是三个完全不同的东西。 Java 垃圾收集器将每个线程堆栈上的每个局部变量都视为一个根引用。它永远不会回收被任何活动函数调用的任何局部变量引用的对象。
【解决方案2】:

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

daemon 属性 - 如 cmets 中所述 - 与此无关。如果只剩下守护线程,Java 虚拟机将关闭,但两种线程的处理方式相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 2020-08-11
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    相关资源
    最近更新 更多