执行者服务关闭

时间:2017-08-14 05:42:41

标签: java multithreading executorservice

我正在使用ExecutorService。我为threads打开了10 for-loop。因此它会打开10 threadsconnection何时关闭?在executor.shutdown()?如果是,它会关闭所有10 threads并再次打开10 threads吗?有什么我可以遵循更好的编码标准,以提高这里的性能?

ExecutorService executor = Executors.newFixedThreadPool(10);
for(String str : stringList){
     for(String str1 : stringList1){
         for(String str2 : stringList2){
              executor.execute(new Runnable() {
                        @Override
                        public void run() {
                        //do something
                        }
          }
     }
}
executor.shutdown();
executor.awaitTermination(24L, TimeUnit.HOURS);

实际上我的想法是遍历loop并将数据保存在文件中并保存每次迭代。所以我想遵循这里的最佳做法,因为我不希望在后期阶段看到任何与服务器相关的问题,例如连接问题/ outOfMemory exceptions。请建议。

我自己实现了这个,但我是multi-threading中的菜鸟。所以,在看到其他一些博客和帖子后,我发布了一些澄清。请帮忙!

2 个答案:

答案 0 :(得分:1)

Executors.newFixedThreadPool(10)完全听起来像它 - 它创建一个线程池,最多10个线程。来自the documentation

  

池中的线程将一直存在,直到明确关闭

因此,最佳做法是尽可能共享线程池。 不要这样做:

for (int i = 0; i < 8; i++) {
    ExecutorService executor = Executors.newFixedThreadPool(10);

    for (String str1 : stringList1) {
        for (String str1 : stringList1) {
            executor.execute(new Runnable(){
                public void run(){ /* Some work... */ }
            });
        }
    }
    executor.shutdown();
    executor.awaitTermination(24L, TimeUnit.HOURS);
}

请注意,在for循环中创建并销毁了新的FixedThreadPool 8次,并且创建/销毁线程池正在创建/销毁多达10个线程。这很糟糕,因为它破坏了使用线程池的意义。如果您要在循环中使用池,请确保在可以的地方重复使用它:

ExecutorService executor = Executors.newFixedThreadPool(10);

for (int i = 0; i < 8; i++) {
    for (String str1 : stringList1) {
        for (String str1 : stringList1) {
            executor.execute(new Runnable(){
                public void run(){ /* Some work... */ }
            });
        }
    }
}

executor.shutdown();
executor.awaitTermination(24L, TimeUnit.HOURS);

最后,最后要注意的是你排队的工作量。如果排队工作的速度快于线程池可以处理的速度,那么队列大小将缓慢增长,直到达到OutOfMemoryException。不幸的是,没有内置的方法可以检查线程池中剩余的任务数量,所以你必须自己完成这个任务。

此概念也适用于服务器 - 如果每秒传入请求的数量高于服务器每秒可处理的请求数,则持续时间足够长,则服务器将耗尽资源并崩溃。解决方案通常是自动扩展和负载平衡,知道如何配置这些东西是业内非常有用的技能。

答案 1 :(得分:1)

  

这里的连接什么时候关闭?在executor.shutdown()?如果是,它会关闭所有10个线程并再次打开10个线程吗?

调用ExecutorService.html#shutdown后,没有新的任务提交到池中,一旦池中没有任务,ExecutorService将被关闭。

void shutdown()

启动有序关闭,其中先前提交的任务已执行,但不会接受任何新任务。如果已经关闭,调用没有额外的效果。

此方法不会等待先前提交的任务完成执行。使用awaitTermination来执行此操作。

触发shutdown后,除非您重新创建ExecutorService

,否则它不会再次打开10个主题
  

实际上我的想法是遍历循环并将数据保存在文件中并保存每次迭代。所以我想遵循这里的最佳实践,因为我不希望在后续阶段看到任何与服务器相关的问题,如连接问题/ outOfMemory异常

不要这样做。让我们等待ExecutorService正确关闭。

解决问题的其他方法:等待完成任务。您可以在以下网址找到更多详细信息:

How to properly shutdown java ExecutorService

另一方面:

newFixedThreadPool创建无界ExecutorService。请注意以下其他替代方案:

How to properly use Java Executor?