java - 灵活的倒计时?

标签 java multithreading concurrency countdownlatch phaser

我现在遇到过两次问题,生产者线程产生 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/

相关文章:

java - 抽象类中 LinkedHashMap 的初始容量应该始终为零吗?

multithreading - 与GCD相比,pthread是否提供任何优势?

java - 从 Servlet 启动独立应用程序的线程

go - 在读取和修改之前锁定 slice

java - Sudoku Solver的代码解释

java - Java中的多重加密技术

java - Java 中的字节码和源代码?

java - Java中的堆栈线程是什么?

java - 不可变对象(immutable对象)在 Java 中完全初始化后是否发布?

asp.net - NHibernate 事务的不良行为