【发布时间】:2011-08-11 10:01:36
【问题描述】:
为什么不能通过将线程的引用设置为 null 并让垃圾收集器将其删除来终止线程?它和其他物体一样,不是吗?
示例:
Thread t = new Thread(new Runnable() {
public void run() {
//...
}
}).start;
t = null;
【问题讨论】:
标签: java multithreading reference terminate
为什么不能通过将线程的引用设置为 null 并让垃圾收集器将其删除来终止线程?它和其他物体一样,不是吗?
示例:
Thread t = new Thread(new Runnable() {
public void run() {
//...
}
}).start;
t = null;
【问题讨论】:
标签: java multithreading reference terminate
它是一个像任何其他对象一样的对象,不是吗 吗?
不,不是。它表示非内存资源。您是否希望文件被删除,因为代表它的对象已被垃圾回收?
事实上,在垃圾回收方面,Thread 对象非常不“像任何其他”对象,因为线程本身就是可达性树的根,所以任何代表正在运行的线程的 Thread 对象的字段(或堆栈上的局部变量)引用的对象根据定义不符合垃圾回收条件。
【讨论】:
JLS section 12.6 这么说:
“可达对象是可以从任何活动线程的任何潜在持续计算中访问的任何对象。”。
由此我们可以推断出活动线程是隐式可访问的,只要它们还活着就不会被垃圾回收。是否存在对 Thread 对象的可达引用无关紧要,尽管(正如@Jon Skeet 所说)线程确实隐含地持有对其自己的 Thread 对象的引用,因此Thread.currentThread() 将起作用。
【讨论】:
出于同样的原因,您不能只将对 JFrame 的引用设置为 null 以使窗口神奇地消失。 JVM 具有对线程的引用,因此即使您忘记了线程,JVM 也不会。您需要正确终止线程,最好是通过结束其主函数。
【讨论】:
您只是将一个变量的值设置为空。
所以,问题是 any 线程是否有效地引用了 Thread 对象。考虑一下新线程本身......它可以很容易地包含
System.out.println(Thread.currentThread());
如果 Thread 对象已被垃圾回收,您希望它做什么?
对象只有在不再有 对它们的实时引用后才会被垃圾回收。任何活动线程都有对其自身的引用。
坦率地说,如果您必须确保确实保留对刚刚启动的线程的引用,以防止它被突然停止,那将是一件痛苦的事。
【讨论】:
Thread 对象有对自身的引用;我说线程做到了。每个线程都贡献任何“实时”引用——有效地在其堆栈上的引用,以及Thread 本身。 (这可能不是实际的实现,但这是 conceptual 推理。)基本上,能够从任何线程获取当前的 Thread 对象是有意义的,因此它是可访问的并且应该不要被垃圾收集。