我现在遇到过两次问题,生产者线程产生 N 个工作项,将它们提交给 ExecutorService
,然后需要等到所有 N 个项目都被处理完。
注意事项
- N 事先未知。如果是这样,我会简单地创建一个
CountDownLatch
然后让生产者线程await()
直到所有工作完成。 - 使用
CompletionService
是不合适的,因为虽然我的生产者线程需要阻塞(即通过调用take()
),但 无法表明所有工作都已完成完成,使生产者线程停止等待。
我目前最喜欢的解决方案是使用整数计数器,并在提交工作项时递增,并在处理工作项时递减。在提交所有 N 个任务后,我的生产者线程将需要等待一个锁,并在收到通知时检查是否 counter == 0
。消费者线程需要通知生产者,如果它已经减少了计数器并且新值是 0。
是否有更好的方法来解决这个问题,或者在 java.util.concurrent
中是否有合适的构造我应该使用而不是“滚动我自己的”?
提前致谢。
最佳答案
java.util.concurrent.Phaser
看起来它对你很有效。它计划在 Java 7 中发布,但最稳定的版本可以在 jsr166 找到的兴趣小组网站。
移相器是一个美化的循环屏障。您可以注册 N 方,并在您准备好时等待他们在特定阶段的推进。
一个关于它如何工作的简单示例:
final Phaser phaser = new Phaser();
public Runnable getRunnable(){
return new Runnable(){
public void run(){
..do stuff...
phaser.arriveAndDeregister();
}
};
}
public void doWork(){
phaser.register();//register self
for(int i=0 ; i < N; i++){
phaser.register(); // register this task prior to execution
executor.submit( getRunnable());
}
phaser.arriveAndAwaitAdvance();
}
关于java - 灵活的倒计时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1636194/