我有以下代码,我有一个大循环,我想并行运行。不幸的是,存在竞争条件,在某些情况下(并非所有情况,不可预测)我在s.awaitTermination
被阻止。没有线程同步,除非在我从集合中删除已完成的线程的末尾,如果集合为空,则调用shutdown
。我哪里错了?仅仅有成千上万的任务被添加到队列中,我不希望他们都试图立即运行,是否有比这更好的模式?
根据Netbeans调试,当我检查队列时,它还有剩下的任务,并且池线程“停在不安全的地方......”。
编辑:按照建议将Thread
更新为Runnable
- 无法解决问题
ExecutorService s = Executors.newFixedThreadPool(8);
final Set<Runnable> threads = new HashSet<>();
for(/*lots of loops*/){
Runnable t = new Runnable(){
public void run(){
//some long task...
synchronized(threads){
threads.remove(this);
if(threads.isEmpty()){
s.shutdown();
}
}
}
}
}
synchronized(threads){
for(Runnable t : threads){
s.submit(t);
}
}
s.awaitTermination(1000, TimeUnit.SECONDS);
答案 0 :(得分:2)
这不是您的问题的解决方案,但它可以帮助您轻松完成相同的任务。看看ExecutorCompletionService它可以执行多个任务,它将为您提供一个可以用来等待的未来。在内部,它为完成的任务使用队列,因此基本上完成了您在此处尝试执行的操作。