以下是摘录,摘录了Brain Goetz的“实践中的Java并发性”一书中的5.11。
我发现以下代码令人困惑。倒数计时闩锁“startGate”的用法似乎有缺陷。 ('endGate'的用法还可以)
public class TestHarness {
public long timeTasks(int nThreads, final Runnable task)
throws InterruptedException {
final CountDownLatch startGate = new CountDownLatch(1);
final CountDownLatch endGate = new CountDownLatch(nThreads);
for (int i = 0; i < nThreads; i++) {
Thread t = new Thread() {
public void run() {
try {
startGate.await();
try {
task.run();
} finally {
endGate.countDown();
}
} catch (InterruptedException ignored) {
}
}
};
t.start();
}
long start = System.nanoTime();
startGate.countDown();
endGate.await();
long end = System.nanoTime();
return end - start;
}
}
行
startGate.countDown()
的执行将通知所有在闩锁上等待的工作线程。但这是否可以保证通知所有nThreads?nTheads可能只执行了run()方法的startGate.await()调用,只有极少数线程,例如2个线程。
并且此时主线程执行
startGate.countDown()
。该调用将仅通知在闩锁上等待的2个线程(nThreads中的线程)。现在,其他线程(nThread-2)的其余部分将在稍后的时间调用
startGate.await()
,但是由于主线程已经发出了通知,因此工作线程(nThreads-2)现在将无限期地等待通知?还是我想念什么?
最佳答案
调用startGate.countDown();
后,计数为零(因为它从1开始)。以后对startGate.await();
的任何调用都不要等待;它已被计算为零。
从Javadocs for CountDownLatch.await()
:
CountDownLatch
仅用于阻塞线程,直到完成另一个线程中的某些工作为止。一旦完成该工作,锁存器将递减计数到零,从而允许任何等待或将来的线程继续通过它。
关于java - 这是对CountdownLatch的不正确使用,初始计数= 1,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20797051/