1

考虑以下场景:

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

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

我知道只要它仍在运行,它someThread本身就不会myObj被 GC,但在我的代码中,它还需要访问存储在 中的值,因此我确保myObj在它仍在运行时仍然存在是很重要的。

4

1 回答 1

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。该引用防止垃圾收集。

于 2012-08-26T01:14:40.927 回答