如何关闭 ExecutorService?
Posted
技术标签:
【中文标题】如何关闭 ExecutorService?【英文标题】:How to shutdown an ExecutorService? 【发布时间】:2012-05-17 06:21:25 【问题描述】:每当我拨打shutdownNow()
或shutdown()
时,它都不会关闭。我读过一些帖子,上面说不能保证关闭 - 有人可以为我提供一个好的方法吗?
【问题讨论】:
请将正确答案标记为已接受 【参考方案1】:最好的方法是我们在 javadoc 中实际拥有的:
以下方法分两个阶段关闭ExecutorService, 首先调用
shutdown
拒绝传入的任务,然后调用shutdownNow
,如有必要,取消任何挥之不去的任务:
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();
【讨论】:
【参考方案2】:典型的模式是:
executorService.shutdownNow();
executorService.awaitTermination();
当调用shutdownNow
时,执行程序(通常)会尝试中断它管理的线程。要使关闭优雅,您需要在线程中捕获中断的异常或检查中断状态。如果您不这样做,您的线程将永远运行,您的执行程序将永远无法关闭。这是因为 Java 中线程的中断是一个协作过程(即,当要求停止时,中断代码必须做某事,而不是中断代码)。
例如,以下代码打印Exiting normally...
。但是如果你注释掉if (Thread.currentThread().isInterrupted()) break;
这一行,它将打印Still waiting...
,因为执行器中的线程仍在运行。
public static void main(String args[]) throws InterruptedException
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable()
@Override
public void run()
while (true)
if (Thread.currentThread().isInterrupted()) break;
);
executor.shutdownNow();
if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS))
System.out.println("Still waiting...");
System.exit(0);
System.out.println("Exiting normally...");
或者,它可以用InterruptedException
写成这样:
public static void main(String args[]) throws InterruptedException
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable()
@Override
public void run()
try
while (true) Thread.sleep(10);
catch (InterruptedException e)
//ok let's get out of here
);
executor.shutdownNow();
if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS))
System.out.println("Still waiting...");
System.exit(0);
System.out.println("Exiting normally...");
【讨论】:
你知道shutdown是否也启动Thread.interrupt()
,从Java API看来shutdown
似乎没有中断线程?
@Bionix1441 不,它没有。 shutdownNow
确实如此。以上是关于如何关闭 ExecutorService?的主要内容,如果未能解决你的问题,请参考以下文章
ExecutorService与ThreadPoolTaskExecutor
如果优雅地关闭ExecutorService提供的java线程池