Java:如果在线程中使用的Runnable被设置为null会发生什么?

7

假设我执行以下操作...

//MyRunnable是我声明的一个类,它实现了Runnable接口。

MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();

r = null;

什么意思是将r设置为null,就像我在上面的代码片段中所做的那样?

+1 请看下面我的回答 :) - Eng.Fouad
不客气。另外,您可以查看我在这里的回答:https://dev59.com/d2ox5IYBdhLWcg3wIRD3#9404727 - Eng.Fouad
3个回答

8
让我用图示解释一下:
1- 在
MyRunnable r = new MyRunnable();

你正在创建一个新的类实例MyRunnable,这个类主要实现了Runnable接口:

enter image description here

2- 在

Thread t = new Thread(r);

你正在创建一个新线程,并通过值传递引用r指向的对象: enter image description here 3- At
r = null;

您正在删除R引用与MyRunnable对象之间的链接,而线程t正在使用它来运行线程:

enter image description here


6

没有任何隐含意义。

线程已经启动。而且无论如何,线程对象都会持有引用,因此在 t 结束之前它不会被垃圾回收。


1
即使线程尚未启动,也没有任何影响,因为线程本身也对可运行对象有一个句柄... - brimborium
@brimborium 确实。我会澄清一下。 - Jivings

3

无。

变量r不是MyRunnable对象本身,它仅仅是你的代码块中对该对象的一个引用。

最初,您创建了一个新的MyRunnable对象。然后,你给它起个名字,即将它赋值给变量r。然后,你把它传递给Thread构造函数(使用该变量来描述你所说的对象)。在那个构造函数中,它几乎肯定会被分配给其他引用(在我使用的JDK中,它是一个称为target的字段)。

稍后,你将你的引用r重新指向另一个对象——在这种情况下,是null对象。这不会对它曾经指向的对象产生任何影响,只会对引用产生影响。同样,它也不会对指向同一对象的其他引用产生影响。

因此,Thread.target引用仍然指向最初创建的同一MyRunnable对象,从线程的视角来看,没有任何变化。

唯一可能的区别是,你(外部)代码片段不再有对它创建的对象的引用。因此,接下来的代码将无法调用该对象的任何方法,或将其作为方法参数传递等。(这不应该是一个问题——或者说令人惊讶——因为你有意将唯一的引用置空了!)


如果没有任何东西持有对特定对象的引用,那么垃圾收集器在下一次运行时将考虑该对象不可达,并回收它。然而,这很少是您需要担心的事情,因为如果您没有对对象的引用,您也不能对它进行任何操作(GC背后的整个原则)。

在这种情况下,MyRunnable不会被垃圾回收,因为Thread仍然持有对它的引用。

话虽如此,如果构造函数的行为不同,不需要存储引用(也许它只使用toString()表示),那么该对象将被视为不可达,并且将被回收。在这两种情况下,垃圾收集器都会做正确的事情——只有当没有东西再引用它时才回收一个对象——而不需要您在代码中担心或知道这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接