此代码在future.get()
上永久阻止。我原以为CancellationException
或InterruptedException
。谁能解释一下呢?
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()取消,因此任何无法响应中断的任务都可能永远不会终止。
答案 0 :(得分:2)
在这种情况下,似乎没有任何阻止线程的尝试。
它试图停止运行Runnables
。在这种情况下,那可能是那个正在睡觉的人。它会被打断,你会抓住异常并返回。 nop Runnable
仍然在队列中。
除非调用InterruptedException
的帖子被中断,否则你不会得到future.get()
。
CancellationException
可以合理地预期,除了技术上,你没有取消未来,你关闭了执行者。
预期的使用似乎是您将Runnables
shutdownNow()
返回列表零售,以便您可以运行它们。这样做有效,但你无法根据自己提交的内容检查它们,因为它们实际上已被装饰(但你不知道这一点,而且它有点令人惊讶,它不会返回您提交的参考文献。
获得此功能有两个不好的解决方法:跟踪您回来的未来并自行取消它们或将Runnables
转发给期货并取消它们,但是这只会起作用,因为这恰好是你正在使用的执行者的内部实现。
是的,这是行为,它在技术上是正确,但它有点奇怪。你想在这里完成什么?