如果解除引用的Java对象启动仍在运行的线程,它仍然会被垃圾收集吗?

时间:2012-08-26 00:58:03

标签: java multithreading garbage-collection

考虑以下情况:

  • 在某个函数myObj中,对象myFunc在本地实例化
  • myObj启动一个运行一些后台任务的线程someThread,例如从插座中读取。
  • myFunc然后返回,导致myObj被解除引用。

在正常情况下,JVM只会垃圾收集myObj。但是,如果someThread仍在运行,情况仍然如此吗?

我了解someThread本身 只要它仍然在运行,但是在我的代码中它还需要访问值存储在myObj中,因此我必须确保myObj在其仍在运行时仍然存在。

1 个答案:

答案 0 :(得分:3)

如果对象没有对它的引用,则该对象仅适用于垃圾回收。您说someThread需要访问存储在myObj中的值,这意味着必须引用myObj。这意味着myObj不符合垃圾回收的条件,除非someThread也符合条件。

你可以保证一个对象永远不会从你下面收集垃圾,所以这是非常安全的:

void foo() {
    final Object something = new String("I'm alive!");
    new Thread() {
        public void run() {
            try {Thread.sleep(10000);} catch (InterruptedException e) {}
            System.out.println(something);
        }
    }.start();
}

something由匿名线程引用,因此在匿名线程完成之前它不符合垃圾回收的条件。

更具体地说,对于您的示例,这也是安全的:

void foo() {
    new ThreadStartingObject("I'm alive!");
}

class ThreadStartingObject {
    private String message;

    public void ThreadStartingObject(String msg) {
        this.message = msg;
        new Thread() {
            public void run() {
                try {Thread.sleep(10000);} catch (InterruptedException e) {}
                System.out.println(message);
            }
        }.start();
    }
}

表示线程的匿名内部类具有对外部this的隐式引用,即ThreadStartingObject的实例。该引用可防止垃圾回收。