如何正确关闭java ExecutorService我有一个简单的java ExecutorService运行一些任务对象(实现Callable)。ExecutorService exec = Executors.newSingleThreadExecutor();List<CallableTask> tasks = new ArrayList<>();// ... create some tasksfor (CallableTask task : tasks) { Future future = exec.submit(task); result = (String) future.get(timeout, TimeUnit.SECONDS); // TASKS load some classes and invoke their methods (they may create additional threads) // ... catch interruptions and timeouts}exec.shutdownNow();在完成所有任务(DONE或TIMEOUT-ed)之后,我尝试关闭执行程序,但它不会停止:exec.isTerminated() = FALSE. 我怀疑某些被执行的任务未正确终止。是的,我知道执行者的关闭不能保证任何事情:除尽力尝试停止处理主动执行任务之外,没有任何保证。例如,典型的实现将通过{@link Thread#interrupt}取消,因此任何未能响应中断的任务都可能永远不会终止。我的问题是,有没有办法确保这些(任务)线程终止?我提出的最佳解决方案是System.exit()在程序结束时调用,但这很简单。
2 回答
胡说叔叔
TA贡献1804条经验 获得超8个赞
从ExecutorService的 Oracle API文档页面推荐的方法:
void shutdownAndAwaitTermination(ExecutorService pool) { pool.shutdown(); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { pool.shutdownNow(); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled if (!pool.awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } } catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted pool.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); }
如果您的池有更多时间关闭,您可以更改
1f (!pool.awaitTermination(60, TimeUnit.SECONDS))
至
while (!pool.awaitTermination(60, TimeUnit.SECONDS))
关闭相关方法的简要概述
启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。
尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。
awaitTermination(long timeout,TimeUnit unit)抛出InterruptedException:
阻止所有任务在关闭请求之后完成执行,或者发生超时,或者当前线程被中断,以先发生者为准。
添加回答
举报
0/150
提交
取消