Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:如果线程中使用的Runnable设置为null,会发生什么情况?_Java_Multithreading_Runnable - Fatal编程技术网

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

Java:如果线程中使用的Runnable设置为null,会发生什么情况?,java,multithreading,runnable,Java,Multithreading,Runnable,假设我做以下事情 //MyRunnable是我声明的一个类,它实现Runnable MyRunnable r = new MyRunnable(); Thread t = new Thread(r); t.start(); r = null; 像我在上面的代码片段中那样将r设置为null有什么意义?无意义 线程已启动。无论如何,线程对象将保留引用,因此在t执行垃圾收集之前,它不会被垃圾收集。什么都没有 变量r不是MyRunnable对象本身;它只是对代码块中该对象的引用 最初创建一个新的My

假设我做以下事情

//MyRunnable是我声明的一个类,它实现Runnable

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

r = null;
像我在上面的代码片段中那样将r设置为null有什么意义?

无意义

线程已启动。无论如何,线程对象将保留引用,因此在
t
执行垃圾收集之前,它不会被垃圾收集。

什么都没有

变量
r
不是
MyRunnable
对象本身;它只是对代码块中该对象的引用

最初创建一个新的
MyRunnable
对象。然后,您“给它命名”/将其分配给变量
r
。然后将其传递到
线程
构造函数中(使用变量描述您正在谈论的对象)。在该构造函数中,它几乎肯定会被分配给其他引用(在我使用的JDK中,它是一个名为
target
的字段)

稍后,您将引用
r
重新指向另一个对象—在本例中为
null
对象。这对用于指向它的对象没有任何影响,只对引用有影响。同样,它对指向同一对象的其他引用没有任何影响

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

唯一的潜在区别是(外部)代码段不再引用它创建的对象。因此,下面的代码将无法调用该对象上的任何方法,或将其作为方法参数等进行传递(考虑到您故意取消了对该对象的唯一引用,这不应该是一个问题,也不会令人惊讶!)


如果没有保存对特定对象的引用,则垃圾回收器将在下一次运行中认为该对象不可访问,并收集它。但是,这很少是您需要担心的事情,因为如果您没有对对象的引用,您无论如何也无法对它做任何事情(GC背后的整个原理)

在这种情况下,
MyRunnable
不会被GCed,因为
线程仍然持有对它的引用


也就是说,如果构造函数的行为不同,并且不存储引用,因为它不需要引用(可能它只是使用
toString()
表示),那么对象将被视为不可访问,并将被收集。在这两种情况下,垃圾收集器都会做正确的事情——当且仅当不再有任何对象引用时才收集对象,而无需在代码中担心或知道这一点。

让我通过图向您解释:

1-At

您正在创建类
MyRunnable
的新实例,该类主要实现
Runnable
接口:

2-At

您正在创建一个新线程,并通过引用r指向的对象传递值:

3-At

您正在删除r引用和
MyRunnable
对象之间的链接,线程
t
正在使用该对象运行线程:


即使线程尚未启动,也不会产生任何影响,因为线程本身在可运行上也有一个句柄…@brimborium True。我会澄清的。+1看看下面我的答案:)@Eng.Fouad Brilliant:)非常感谢!不客气。另外,请看我的回答:
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
r = null;