Java的executionService.shutdownNow()没有取消或中断线程

时间:2016-06-09 03:38:42

标签: java multithreading concurrency future executorservice

此代码在future.get()上永久阻止。我原以为CancellationExceptionInterruptedException。谁能解释一下呢?

ExecutorService es = Executors.newSingleThreadExecutor();

es.execute(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {/*squelch*/}
});

Future<Integer> future = es.submit(() -> 1);
es.shutdownNow();
try {
    future.get();
} catch (ExecutionException e) {e.printStackTrace();}

docs说没有保证,但我仍然发现观察到的行为很奇怪,因为它意味着停止失败是由行为不端的线程引起的。在这种情况下,似乎没有任何尝试停止该线程。

  

除了尽力尝试停止处理主动执行任务之外,没有任何保证。例如,典型的实现将通过Thread.interrupt()取消,因此任何无法响应中断的任务都可能永远不会终止。

1 个答案:

答案 0 :(得分:2)

  

在这种情况下,似乎没有任何阻止线程的尝试。

它试图停止运行Runnables。在这种情况下,那可能是那个正在睡觉的人。它会被打断,你会抓住异常并返回。 nop Runnable仍然在队列中。

除非调用InterruptedException的帖子被中断,否则你不会得到future.get()

CancellationException可以合理地预期,除了技术上,你没有取消未来,你关闭了执行者。

预期的使用似乎是您将Runnables shutdownNow()返回列表零售,以便您可以运行它们。这样做有效,但你无法根据自己提交的内容检查它们,因为它们实际上已被装饰(但你不知道这一点,而且它有点令人惊讶,它不会返回您提交的参考文献。

获得此功能有两个不好的解决方法:跟踪您回来的未来并自行取消它们或将Runnables转发给期货并取消它们,但是这只会起作用,因为这恰好是你正在使用的执行者的内部实现。

是的,这是行为,它在技术上是正确,但它有点奇怪。你想在这里完成什么?