Golang有一种称为WaitGroup
的东西,有点像Java CompletionService
或CountDownLatch
或Semaphore
或后者的某种组合。
我不完全确定如何在Java中实现WaitGroup。我可以想象一个带有某种Poison消息的自定义CompletionService将是要走的路(因为队列不能说它们什么时候完成)但是也许有更好的并发数据结构/锁?
编辑我在下面使用Semaphore
发布了一个可能的解决方案,我认为这比使用thread.join
更类似。
答案 0 :(得分:3)
WaitGroup
具有Add(delta)
方法,可在创建WaitGroup
后调用。 CountDownLatch
不支持此功能,需要提前指定任务数量。在这种情况下,可以使用JDK7 Phaser
:
phaser.register = wg.Add(1)
phaser.arrive = wg.Done
phaser.await = wg.Wait
答案 1 :(得分:1)
public class WaitGroup {
private int jobs = 0;
public synchronized void add(int i) {
jobs += i;
}
public synchronized void done() {
if (--jobs == 0) {
notifyAll();
}
}
public synchronized void await() throws InterruptedException {
while (jobs > 0) {
wait();
}
}
}
答案 2 :(得分:0)
在查看golang文档并确认Semaphore赢得了大量许可后,我认为设置为Semaphore
的{{1}}最接近golang {{1} }。
Integer.MAX_VALUE
可能更类似于将WaitGroup与goroutine一起使用的方式,因为它处理线程的清理,但是像WaitGroup
一样孤立的thread.join
是不可知的增加它。
CountdownLatch无法正常工作,因为您需要先了解要运行的线程数,并且无法增加CountdownLatch。
假设信号量设置为WaitGroup
:
Semaphore
== Integer.MAX_VALUE
wg.Add(n)
== semaphore.acquire(n)
并在你希望一切停止的主题中:
wg.Done()
== semaphore.release()
但是我不确定所有的语义是否存在,所以我现在暂时不会将此标记为正确。
答案 3 :(得分:-1)
不,Go中没有'CountDownLatch'。
sync.WaitGroup
可能具有“等待任务完成”功能,但此API的Add()
并未发生,因为Done()
。