英文:
What is the Java equivalent of Golang's WaitGroup
问题
Golang有一种叫做WaitGroup
的东西,类似于Java中的CompletionService
、CountDownLatch
或Semaphore
,或者是这些的某种组合。
我不太确定如何在Java中实现一个WaitGroup。我想象中可能需要使用自定义的CompletionService,并带有某种毒药消息(因为队列无法表示它们何时完成),但也许有更好的并发数据结构/锁?
编辑:我在下面发布了一个可能的解决方案,使用Semaphore
,我认为这比使用thread.join
更类似。
英文:
Golang has something called a WaitGroup
which is sort of like in Java a CompletionService
or a CountDownLatch
or a Semaphore
or some combination of the latter.
I'm not entirely sure how you would implement a WaitGroup in Java. I would imagine a custom CompletionService with some sort of Poison message would be the route to go (since queues can't say when they are done) but perhaps there is a better concurrent data structure/lock?
EDIT I posted a possible solution below using Semaphore
that I think is more analogous than using thread.join
.
答案1
得分: 7
WaitGroup
有一个Add(delta)
方法,可以在创建WaitGroup
之后调用。CountDownLatch
不支持这个功能,需要提前指定任务的数量。在这种情况下,可以使用JDK7的Phaser
代替:
phaser.register = wg.Add(1)
phaser.arrive = wg.Done
phaser.await = wg.Wait
英文:
WaitGroup
has Add(delta)
method that can be called after a WaitGroup
has been created. CountDownLatch
doesn't support this, number of tasks needs to be specified in advance. JDK7 Phaser
can be used instead in this case:
phaser.register = wg.Add(1)
phaser.arrive = wg.Done
phaser.await = wg.Wait
答案2
得分: 5
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();
}
}
}
英文:
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();
}
}
}
答案3
得分: 1
感谢@kostya的回答。
我使用Phaser编写了一个WaitGroup类。
public class WaitGroup {
Phaser phaser = new Phaser(1);
public void add() {
phaser.register();
}
public void done() {
phaser.arrive();
}
public void await() {
phaser.arriveAndAwaitAdvance();
}
}
英文:
Thanks to @kostya's answer.
I write a WaitGroup class with Phaser
public class WaitGroup {
Phaser phaser = new Phaser(1);
public void add() {
phaser.register();
}
public void done() {
phaser.arrive();
}
public void await() {
phaser.arriveAndAwaitAdvance();
}
}
答案4
得分: 0
在查看了golang文档并确认Semaphore不会因为大量许可证而中断后,我认为将Semaphore
设置为Integer.MAX_VALUE
是最接近golang的WaitGroup
的方式。
thread.join
可能更类似于使用goroutines的WaitGroup的方式,因为它处理线程的清理,然而,一个独立的WaitGroup
就像一个Semaphore
一样,不关心它的增量。
CountdownLatch不起作用,因为你需要事先知道要运行多少个线程,而且你不能增加CountdownLatch。
假设信号量设置为Integer.MAX_VALUE
:
wg.Add(n)
== semaphore.acquire(n)
wg.Done()
== semaphore.release()
在你想要停止一切的线程中:
wg.Wait()
== semaphore.acquire(Integer.MAX_VALUE)
然而,我不确定所有的语义是否都能传递过来,所以我暂时不会将其标记为正确。
英文:
After looking at the golang doc and confirming that Semaphore won't break with an enormous amount of permits I think a Semaphore
set to Integer.MAX_VALUE
is the closest to a golang WaitGroup
.
The thread.join
is probably more similar to how you would use WaitGroup with goroutines since it deals with the cleanup of the threads however an isolated WaitGroup
just like a Semaphore
is agnostic of what increments it.
CountdownLatch doesn't work because you need to know a priori how many threads you want to run and you cannot increment a CountdownLatch.
Assuming the semaphore is set to Integer.MAX_VALUE
:
wg.Add(n)
== semaphore.acquire(n)
wg.Done()
== semaphore.release()
and in your thread where you want everything to stop:
wg.Wait()
== semaphore.acquire(Integer.MAX_VALUE)
However I'm not sure all the semantics carryover so I'm not going to mark this correct for now.
答案5
得分: -3
不,Go语言中没有'CountDownLatch'。
sync.WaitGroup
可能具有等待任务完成的功能,但是该API的Add()
并不发生在Done()
之前。
英文:
No, there is no 'CountDownLatch' in Go.
sync.WaitGroup
may have the 'wait task finish' feature, but this API's Add()
doesn't happens-befor Done()
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论