Runnable 中的方法引用使对象 GC 安全吗?
Method reference in a Runnable makes object GC safe?
例如在给定的代码中,
@Singleton
public class MyExecutor {
ExecutorService executorService;
public void execute(Runnable runnable) {
executorService.submit(runnable);
}
}
class A {
public void a(String x) {
// do something
}
MyExecutor executor;
// Injected via DI, always is same object
A(MyExecutor executor) {
this.executor = executor;
}
public void run() {
executor.execute(() -> a("Whatever"));
}
}
所以我的问题是假设我非常频繁地创建 A
并调用它们的 a.run()
然后忘记它,我的 A
对象不会被 GC 收集直到MyExecutor
处理完了吗?
在我看来应该是这样,否则 MyExecutor
怎么知道要执行哪个实例?
所以基本上我的问题是,调用者对象是否将实例方法引用作为 Runnable
/Callable
/Consumer
..etc 在传递 Runnable
/Callable
/Consumer
有人持有他们的参考资料吗?
当然可以。
这很简单:只要 "active" 对象保持对某个其他对象 X 的引用,其他对象 X 就没有资格进行垃圾回收。
并且可以安全地假设执行者跟踪提交给它的所有任务。任务完成后,不再需要任何对传递给它的 task/runnable 的引用。所以执行者忘记了它,然后 task/runnable 有资格进行 GC。
请注意:没有 "method reference" 个对象!方法引用或 lambdas 基本上是一些 class 的对象(Task 或 Runnable,例如取决于上下文)。方法引用首先是一个 syntax 元素!
例如在给定的代码中,
@Singleton
public class MyExecutor {
ExecutorService executorService;
public void execute(Runnable runnable) {
executorService.submit(runnable);
}
}
class A {
public void a(String x) {
// do something
}
MyExecutor executor;
// Injected via DI, always is same object
A(MyExecutor executor) {
this.executor = executor;
}
public void run() {
executor.execute(() -> a("Whatever"));
}
}
所以我的问题是假设我非常频繁地创建 A
并调用它们的 a.run()
然后忘记它,我的 A
对象不会被 GC 收集直到MyExecutor
处理完了吗?
在我看来应该是这样,否则 MyExecutor
怎么知道要执行哪个实例?
所以基本上我的问题是,调用者对象是否将实例方法引用作为 Runnable
/Callable
/Consumer
..etc 在传递 Runnable
/Callable
/Consumer
有人持有他们的参考资料吗?
当然可以。
这很简单:只要 "active" 对象保持对某个其他对象 X 的引用,其他对象 X 就没有资格进行垃圾回收。
并且可以安全地假设执行者跟踪提交给它的所有任务。任务完成后,不再需要任何对传递给它的 task/runnable 的引用。所以执行者忘记了它,然后 task/runnable 有资格进行 GC。
请注意:没有 "method reference" 个对象!方法引用或 lambdas 基本上是一些 class 的对象(Task 或 Runnable,例如取决于上下文)。方法引用首先是一个 syntax 元素!