Java ExecutorService - 如果awaitTermination()失败怎么办?

时间:2016-09-09 14:41:03

标签: java multithreading

如果我有以下代码,那么工作正常:

ExecutorService service = Executors.newFixedThreadPool(100);

[....]

List<Future<SomeObject>> futures = service.invokeAll(callables);
for (Future f : futures) {
    f.get();
}

// shutdown the service after all Callables are finished.
service.shutdown();

boolean serviceIsShutDown = service.awaitTermination(5, TimeUnit.SECONDS);
if (serviceIsShutDown) {
    System.out.println("Service terminated normally. All ok.");
} else  {
    // What if it's not shutDown?
    [...]
    // this? 
    //service = null;
}   

问题:如果通话

怎么办?
boolean serviceIsShutDown = service.awaitTermination(5, TimeUnit.SECONDS);

返回false,因为超时命中?

我猜ExecutorService中的Threads将保持WAIT状态。什么是最好的解决方案? 将服务设置为null并让GarbageCollector删除它?但相关的线程会发生什么?它是否会被垃圾收集,因为仍有参考文献?

代码通常有效,但只是好奇。如果返回false该怎么办?

2 个答案:

答案 0 :(得分:2)

如果您想“强行”终止您的ExecutorService,请使用:

执行shutdownNow()

在这里查看说明:

enter image description here

答案 1 :(得分:2)

如果awaitTermination()在您的示例中返回false,您可以选择尝试拨打shutdownNow()。此方法将尽力取消仍在执行的所有任务,但它不保证任何内容。一些执行不当的任务可能没有取消策略,只能永远运行。在这种情况下,线程将永远不会被终止,执行程序永远不会被垃圾收集。

此类任务还会阻止程序正常终止(如果不将工作线程标记为守护程序)。

例如,如果您的任务只包含一个空的无限循环,即使您调用shutdownNow(),它也不会被取消。

也可能存在任务没有正确的取消策略,并且运行时间过长(但不是永久)的情况。例如,它有一个非常长的空循环。您可能无法通过shutdown() / shutdownNow()关闭正在执行此类任务的池,但迟早它将完成其工作,并且该线程将与执行程序一起终止。