以下是摘录,摘录了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/

10-09 04:55