使用java.util.concurrent.CountdownLatch相对于java.util.concurrent.Semaphore是否有优势?就我所知,以下片段几乎是等效的:
1. Semaphore
final Semaphore sem = new Semaphore(0);
for (int i = 0; i < num_threads; ++ i)
{
Thread t = new Thread() {
public void run()
{
try
{
doStuff();
}
finally
{
sem.release();
}
}
};
t.start();
}
sem.acquire(num_threads);
2: CountDownLatch
final CountDownLatch latch = new CountDownLatch(num_threads);
for (int i = 0; i < num_threads; ++ i)
{
Thread t = new Thread() {
public void run()
{
try
{
doStuff();
}
finally
{
latch.countDown();
}
}
};
t.start();
}
latch.await();
除了第二种情况下的闩锁无法重复使用,更重要的是您需要事先知道将创建多少个线程(或在所有线程启动之前等待,然后再创建闩锁)。那么,在什么情况下闩锁可能更可取呢?
CountDownLatch
不仅可以按照OP的方式“安全使用”,而且实际上它是CountDownLatch
的预期使用场景之一,其中Semaphore
并不适合,至少在语义上是这样。从概念上讲,Semaphore
用于并发访问共享资源,而CountDownLatch
用于等待某些任务完成后才能抬起闸门让其他线程出去/运行。 - wlnirvana