【问题标题】:Java : What happens if a Runnable that is being used in a thread is set to null?Java:如果线程中使用的 Runnable 设置为 null 会发生什么?
【发布时间】:2012-06-16 05:18:24
【问题描述】:

说我做以下...

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

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

r = null;

像我在上面的代码 sn-p 中那样将 r 设置为 null 有什么影响?

【问题讨论】:

标签: java multithreading runnable


【解决方案1】:

没有影响。

线程已经开始。无论如何,线程对象将保留引用,因此在t 之前不会被垃圾收集。

【讨论】:

  • 即使 Thread 尚未启动也没有任何影响,因为 Thread 本身在 Runnable 上也有句柄...
  • @brimborium 真的。我会澄清的。
【解决方案2】:

什么都没有。

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

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

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

所以Thread.target 引用仍然指向您最初创建的同一个MyRunnable 对象,从线程的角度来看,没有任何改变。

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


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

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

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

【讨论】:

    【解决方案3】:

    让我通过数字向你解释一下:

    1- 在

    MyRunnable r = new MyRunnable();
    

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

    2- 在

    Thread t = new Thread(r);
    

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

    3- 在

    r = null;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多