如果一个取消引用的java对象启动了一个仍在运行的线程,它是否仍会被垃圾收集?

6mzjoqzu  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(303)

考虑以下场景:
一个物体 myObj 在某个函数中本地示例化 myFunc . myObj 开始一个线程 someThread 它运行一些后台任务,例如从套接字读取。 myFunc 然后返回,导致 myObj 取消引用。
在正常情况下,jvm只会进行垃圾收集 myObj . 但是,如果 someThread 仍在运行,是否仍会是这种情况?
我明白 someThread 只要它还在运行,它本身就不会是gc的,但在我的代码中,它还需要访问存储在中的值 myObj 所以我要确保 myObj 在它仍在运行时仍然存在。

sy5wg1nm

sy5wg1nm1#

对象只有在没有引用的情况下才有资格进行垃圾收集。你这么说 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` . 该引用防止垃圾回收。

相关问题