假设我执行以下操作...
//MyRunnable是我声明的一个类,它实现了Runnable接口。
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
r = null;
什么意思是将r设置为null,就像我在上面的代码片段中所做的那样?
假设我执行以下操作...
//MyRunnable是我声明的一个类,它实现了Runnable接口。
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
r = null;
MyRunnable r = new MyRunnable();
MyRunnable
,这个类主要实现了Runnable
接口:
2- 在
Thread t = new Thread(r);
r = null;
您正在删除R引用与MyRunnable对象之间的链接,而线程t正在使用它来运行线程:
没有任何隐含意义。
线程已经启动。而且无论如何,线程对象都会持有引用,因此在 t
结束之前它不会被垃圾回收。
无。
变量r
不是MyRunnable
对象本身,它仅仅是你的代码块中对该对象的一个引用。
最初,您创建了一个新的MyRunnable
对象。然后,你给它起个名字,即将它赋值给变量r
。然后,你把它传递给Thread
构造函数(使用该变量来描述你所说的对象)。在那个构造函数中,它几乎肯定会被分配给其他引用(在我使用的JDK中,它是一个称为target
的字段)。
稍后,你将你的引用r
重新指向另一个对象——在这种情况下,是null
对象。这不会对它曾经指向的对象产生任何影响,只会对引用产生影响。同样,它也不会对指向同一对象的其他引用产生影响。
因此,Thread.target
引用仍然指向最初创建的同一MyRunnable
对象,从线程的视角来看,没有任何变化。
唯一可能的区别是,你(外部)代码片段不再有对它创建的对象的引用。因此,接下来的代码将无法调用该对象的任何方法,或将其作为方法参数传递等。(这不应该是一个问题——或者说令人惊讶——因为你有意将唯一的引用置空了!)
如果没有任何东西持有对特定对象的引用,那么垃圾收集器在下一次运行时将考虑该对象不可达,并回收它。然而,这很少是您需要担心的事情,因为如果您没有对对象的引用,您也不能对它进行任何操作(GC背后的整个原则)。
在这种情况下,MyRunnable
不会被垃圾回收,因为Thread
仍然持有对它的引用。
话虽如此,如果构造函数的行为不同,不需要存储引用(也许它只使用toString()
表示),那么该对象将被视为不可达,并且将被回收。在这两种情况下,垃圾收集器都会做正确的事情——只有当没有东西再引用它时才回收一个对象——而不需要您在代码中担心或知道这一点。