【问题标题】:Does the runnable class go out of scope when a java thread ends?java线程结束时可运行类是否超出范围?
【发布时间】:2012-06-06 19:34:23
【问题描述】:

如果我创建一个实现 Runnable 的对象,并用它启动一个线程...

ArrayList<Thread> threadlist = new ArrayList<Thread>();
{
  MergeThread mmt = new MergeThread();
  Thread t = new Thread(mmt);
  threadlist.add(mmt);
  t.start();
}

t.join();
Thread t = threadlist.get(0);

此时 mmt 保证存在,或者如果垃圾收集得到它,它可能已经消失。

我要问的是 Thread 对象在线程结束后是否保留了 Runnable 类。

编辑:上面应该说有一个错误 线程列表.add(t);

【问题讨论】:

  • 据我所知,一旦线程结束,对象就会超出范围,除非另一个对象正在引用它。
  • 代码似乎无效,因为在您执行 t.join() 的地方没有 t inscope。

标签: java multithreading


【解决方案1】:

来自source of the Thread class

/**
 * This method is called by the system to give a Thread
 * a chance to clean up before it actually exits.
 */
private void exit() {
if (group != null) {
    group.remove(this);
    group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
    threadLocals = null;
    inheritableThreadLocals = null;
    inheritedAccessControlContext = null;
    blocker = null;
    uncaughtExceptionHandler = null;
}

因此系统调用Thread#exit() 并释放对target(这是线程正在运行的可运行对象)的引用。

还有一个bug report #4006245 on bugs.sun.com指的是清除target引用。

【讨论】:

  • 类的some实现的私有方法并没有真正给出权威的答案...
  • 这不是 some 实现。是 OpenJDK,它是 Sun/Oracle 实现的基础。所以我认为它在某种程度上是权威的。当然,在官方规范中查找这样的内容会更好。
  • 在源代码引用的错误数据库中添加了一个链接。
  • 代码总是一个很好的权威,当然比文档更好:-) 这就是我想要的。 Thread 对象确实放弃了对可运行对象的引用。
【解决方案2】:

mmt 被添加到threadList 所以只要threadList 本身是可访问的并且仍然持有它,它就不会被垃圾收集,这仍然是代码示例的最后一行的情况,无论你的第一个t(在中间块中)是否仍然持有对它的引用。

【讨论】:

  • no, mmt is not added the Thread object is added, and the thread object is built with mmt.线程结束后 mmt 是否在 Thread 对象内部保持并不明显。
  • @stu uuuh... 否:threadlist.add(mmt) 正在将 mmt 添加到您的列表中。我认为您在这里误解了一些东西,或者您显示的代码不是您的意思。
  • 我的错误,有一个错字,我已经更正了。该程序不会以其他方式编译。
  • @stu if MergeThread extends Thread 然后代码应该编译。问题(和答案)现在显然完全不同了。
  • @stu 实际上,即使经过更正,我仍然不明白您的问题:线程类没有提供获取传递给构造函数的 Runnable 对象的 getter。所以无论它是否被取消都没有区别:你无论如何都无法访问它......
【解决方案3】:

您发布的代码对我来说不是很清楚。但是,关于

此时 mmt 保证存在,或者如果垃圾收集得到它,它可能已经消失。

我可以这样说:如果 仍然可以得到它,垃圾收集器将不会回收该对象(如果你无法得到它,那么没有意义担心对象是否已被 GC 处理)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 2013-05-09
    相关资源
    最近更新 更多