我正在使用ExecutorService
。我为threads
打开了10 for-loop
。因此它会打开10 threads
,connection
何时关闭?在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
中的菜鸟。所以,在看到其他一些博客和帖子后,我发布了一些澄清。请帮忙!
答案 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
实际上我的想法是遍历循环并将数据保存在文件中并保存每次迭代。所以我想遵循这里的最佳实践,因为我不希望在后续阶段看到任何与服务器相关的问题,如连接问题/ outOfMemory异常
不要这样做。让我们等待ExecutorService
正确关闭。
解决问题的其他方法:等待完成任务。您可以在以下网址找到更多详细信息:
How to properly shutdown java ExecutorService
另一方面:
newFixedThreadPool
创建无界ExecutorService
。请注意以下其他替代方案: