【问题标题】:Java newSingleThreadExecutor garbage collectionJava newSingleThreadExecutor 垃圾回收
【发布时间】:2016-09-29 14:36:00
【问题描述】:

考虑以下 Java 代码

void doSomething(Runnable r1, Runnable r2){
  Executor executor = Executors.newSingleThreadExecutor();
  executor.execute(r1);
  executor.execute(r2);
}

当我调用 doSomething 方法时,会创建执行器并依次执行任务 r1 和 r2。

我的问题是:一旦两个任务 r1 和 r2 终止会发生什么?

我想executor对象会被垃圾回收,但我不知道它是否也会被关闭。如果executor为其执行创建了一个新线程,这个线程会不会导致资源泄露?

【问题讨论】:

  • 您可以使用 ExecutorService,然后在提交任务执行后调用 shutdown。 ES 会等到任务完成后才会终止。
  • 您也可以使用零核心线程的ThreadPoolExecutor,以便在没有要运行的任务时回收线程。

标签: java multithreading executor


【解决方案1】:

我想 executor 对象会被垃圾回收,但我没有 知道它是否也会被关闭。

实际上Executors.newSingleThreadExecutor()在木头下创建了一个FinalizableDelegatedExecutorService实例,它会在finalize上调用shutdown,表示在垃圾回收时会自动关闭。

但是,我不认为过度依赖它是一个好主意,因为它更多的是一个可能会从一个版本更改为另一个版本的实现细节,您应该明确地关闭它,而不是防止任何意外错误。

【讨论】:

  • 您对创建 FinalizableDelegatedExecutorService 实例这一事实有任何引用吗?
  • @ichfarbstift 代码。但是代码的这方面并不能“通过合同”得到保证,所以不要依赖它。在您的ExecutorService 参考丢失之前致电shutdown()。请注意,即使 shutdown() 已被调用,ExecutorService 也会一直运行,直到之前提交的任务完成。
  • @Nicolas 就是说如果我想确定上面代码中线程被销毁的executor应该是ExecutorService的一个实例,我应该在execute(r2)之后调用executor.shutdown() )?
  • 我最近看到了这个,不知道 ExecutorService 实际最终确定的场景是什么。由于活动线程引用了 ES,因此它似乎永远不会真正完成。发生这种情况的唯一方法是,如果没有活跃的线程,那么我想它会被最终确定。
【解决方案2】:

ExecutorService的文档我们可以读到

"应关闭未使用的 ExecutorService 以允许回收 它的资源。”

基本上,您将不得不手动终止执行器服务。虽然 executor 对象本身会被垃圾回收,但它的内部线程不会。

【讨论】:

  • 创建的线程引用了它们运行的​​ExecutorService。只要它们还活着,ExecutorService 就没有资格进行 GC。
  • @erickson 该文档不承诺如果您的代码失去对ExecutorService 的引用,将会发生任何特别的事情,并且它确实警告您如果您想要“资源”,您应该关闭它被回收。如果您希望您的代码“在任何地方运行”,那么您可能应该相信 javadoc 所说的内容,而不是假设 javadoc 没有说什么。
  • 很久以前,在Executor 之前,我写了一个非常漂亮的线程池,可以检测它是否被不当丢弃并关闭它的worker;工作人员通过弱引用引用了“拥有”他们的池。
【解决方案3】:

只有当对象没有被 GC 根引用时,对象才能被 GC。什么是 GC 根?最常见的是系统类和正在运行的线程。 ExecutorService 将创建和维护正在运行的线程,因此即使 ES 是在方法中创建的,ES 仍然是可访问的,而不是 GC。

正如其他人提到的,您需要关闭 ES 才能对其进行 GC。

【讨论】:

    猜你喜欢
    • 2014-03-09
    • 1970-01-01
    • 2011-06-25
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多