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

Java's executionService.shutdownNow() not cancelling or interrupting thread

此代码在 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 说没有保证,但我仍然发现观察到的行为很奇怪,因为它暗示停止失败是由行为不当的线程引起的。在这种情况下,似乎没有任何停止线程的尝试。

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.

In this case there doesn't seem to be any attempt to stop the thread.

它试图阻止 运行宁 Runnables。在这种情况下,那可能就是那个正在睡觉的人。它将被中断,您将捕获异常并 return。 nop Runnable 还在队列中。

除非调用 future.get() 的线程被中断,否则您不会得到 InterruptedException

CancellationException 是合理的预期,除了 技术上 ,你没有取消 Future,你关闭了执行者。

预期 用途似乎是零售 Runnables shutdownNow() return 列表,这样您就可以 运行 他们。这行得通,但你不能根据你提交的内容检查它们,因为它们实际上已经被装饰过(但你不知道这一点,而且它没有 return 参考你已提交)。

获得此功能有两种不好的解决方法:跟踪您返回的期货并自行取消它们,或者将 shutdownNow() 编辑的 Runnables 转换为期货并取消它们,但这只有效,因为它恰好是您正在使用的执行程序的内部实现。

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