【问题标题】:Cleaning up thread submitted using ExecutorService清理使用 ExecutorService 提交的线程
【发布时间】:2017-12-01 19:01:49
【问题描述】:

我的代码如下:

public Future<String> getFuture() {
  ExecutorService executorService = Executors.newSingleThreadExecutor();
  Future<String> future = executorService.submit(() -> {
    //do something
    return "test string";
  });
  executorService.shutDown(); // is this correct?
  return future;
}

我正在从其他类调用此服务以获得未来:

 Future<String> future = getFuture();
 String result = future.get();
 future.cancel(true); // will this assure that there wont be any thread leak?

现在executorService.shutDown()future.cancel(true) 将确保不会有线程泄漏?

请注意,在调用future.cancel(true) 后,当我在Thread.getAllStackTraces() 的结果中检查当前正在运行的线程时,我仍然可以找到未来执行的线程。

【问题讨论】:

  • 获取未来值后,有没有查看当前运行的线程?
  • 是的,shutDown() 是正确的。没有线程泄漏。您可能会看到线程停留了一段时间,但如果这可能导致线程泄漏,那将是一个重大错误。
  • @efekctive 是的,我已经更新了代码以避免混淆。
  • @Kayaman doe 在调用 future.get() 之前调用 executorService.shutDown() 保证它不会中断未来任务的执行?我很困惑,因为 shutdown 的文档指出“此方法不会等待先前提交的任务完成执行。”
  • 就是这样。如果有泄漏,您会立即注意到

标签: java multithreading java-threads


【解决方案1】:

你问错问题了!

在一个方法中创建一个服务然后把它扔掉是没有意义的。

创建该服务实例并不是免费的。这种抽象的整个想法是确保高效使用基础设施元素!

换句话说:退后一步,重新设计你的设计;这样这个服务就变成了某个类的field!是的,这可能会变得很复杂。但最有可能的是,与继续您的问题中显示的方法相比,花时间在那个角落会获得更多的长期回报。

【讨论】:

    【解决方案2】:
    • 创建执行程序然后在每个方法调用中将其丢弃是一个坏主意。

    现在没有 executorService.shutDown() 和 future.cancel(true) 来保证不会有线程泄漏?

    没有。
    executorService.shutdown() 只会继续运行当前任务并拒绝新提交的任务。

    future.cancel(true) 将中断当前正在运行的相应任务(但您有责任检查任务是否被中断并尽快完成任务的执行)

    请注意,在调用 future.cancel(true) 后,当我在 Thread.getAllStackTraces() 的结果中检查当前正在运行的线程时,我仍然可以找到执行 future 的线程。

    正如我之前提到的,future.cancel(true) 不会停止线程。它只会发送中断。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多