正确关闭ThreadPoolExecutors

时间:2015-07-29 07:49:04

标签: java multithreading

我是java并发的新手,想问下面的基本问题。我正在创建一个ThreadPoolExecutor来提高性能,如下所示:

int n = Runtime.getRuntime().availableProcessors()
ExecutorService executor = Executors.newFixedThreadPool(n);
for( int i = 0; i < n; i++)
            executor.execute(new Work());

线程池中的所有线程完成任务后,我需要正确关闭池。我试过这个:

while(true){
    if(executor.isTerminated()){
        executor.shutdownNow();
        break;
    }
}

但是我不确定,因为我认为我们浪费了大量的处理器资源来确定执行者的终止。

什么是正确的解决方案?

UPD:可运行的任务:

public class Work implements Runnable{

    private String sql;

    public Work() {
        //init sql
    }
    @Override
    public void run() {
        JdbcTemplate template = new JdbcTemplate(dataSource);
        @SuppressWarnings("unchecked")
        List<Integer> ints = template.queryForList(sql, Integer.class);
        //Storing the list into a global cache
    }

}

3 个答案:

答案 0 :(得分:2)

在关闭ExecutorService时,似乎有一些神秘的东西。

来自the documentation of shutdown()

  

启动有序关闭,其中执行先前提交的任务,但不接受任何新任务。

所以你要做的就是在提交所有任务后调用shutdown(),确切的时间无关紧要。它们不必在那时完成。 ThreadPoolExecutor将完成所有任务,然后清理所有资源。

无论你是否等待,它都会这样做。因此,您无需等待,只要在您确信不会提交新任务时调用shutdown(),其余内容将尽快发生。

答案 1 :(得分:1)

它说:

  

除了努力尝试停止处理之外,没有任何保证   积极执行任务。例如,典型的实现方式   通过Thread.interrupt()取消,因此任何无法响应的任务   中断可能永远不会终止。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()

所以请改用awaitTermination。对于花费时间的线程,使用布尔变量作为volatile并检查它是否设置在外部。如果设置然后退出等等

答案 2 :(得分:0)

  try {
            executor = Executors.newSingleThreadExecutor();
            future = executor.submit(task);
            executor.shutdown();
            executor.awaitTermination(5, TimeUnit.SECONDS);
        }
        finally {
            if (Objects.nonNull(executor) && !executor.isTerminated()) {
                LOGGER.error("cancelling all non-finished tasks");
            }
            if (Objects.nonNull(executor)) {
                executor.shutdownNow();
                LOGGER.info("shutdown finished");
            }
        }

这样你关闭执行器并等待5秒钟完成所有任务,最后调用executor.shutdownNow()完全杀死执行者。

这是关闭执行程序的最佳方法。

相关问题