Ссылка на метод в Runnable делает объект GC безопасным? - PullRequest
3 голосов
/ 14 апреля 2019

Например, в данном коде,

@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 s и вызываю их a.run(), а затем забываю об этом, будет ли Aобъект не будет собран GC до тех пор, пока MyExecutor не закончит с ними обработку?

Мне кажется, что так и должно быть, иначе MyExecutor когда-нибудь узнает, какой экземпляр выполнить?

Таким образом, в основном мой вопрос заключается в том, является ли объект вызывающего объекта, передающий ссылку на метод экземпляра, как Runnable / Callable / Consumer .. и т. Д. Безопасным для GC до переданного Runnable / Callable / Consumer кто-то держит ссылку на них?

1 Ответ

1 голос
/ 14 апреля 2019

Конечно.

Это очень просто: пока «активный» объект сохраняет ссылку на какой-то другой объект X, этот другой объект X не подходит для сборки мусора.

И можно с уверенностью предположить, что исполнитель отслеживает все представленные ему задачи. Когда задача завершена, любая ссылка на задачу / исполняемый файл, переданная ей ... больше не нужна. Таким образом, исполнитель забывает об этом, и , а затем , что задача / runnable становится подходящим для GC.

И, пожалуйста, обратите внимание: нет объектов "ссылки на метод"! Ссылки на методы или лямбда-выражения в основном являются объектами некоторого класса (например, Task или Runnable, в зависимости от контекста). Ссылки на методы - это, прежде всего, элемент синтаксис !

...