Java:如果线程中使用的Runnable设置为null,会发生什么情况?
假设我做以下事情 //MyRunnable是我声明的一个类,它实现RunnableJava:如果线程中使用的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 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;