转载请注明出处:http://blog.csdn.net/linxdcn/article/details/72857496
CountDownLatch提供了一种能使多个线程触发同一条件,开始运行的机制。
打个比方,银行金库有3把钥匙(CountDownLatch的count为3),得到一把钥匙(调用countDown函数),就离获得通行的条件越近。当3把钥匙都已经获取时(count变为0),银行金库将被打开(线程可以通行)。
1 使用方法
public class CountDownLatchDemo {
public static void main(String[] args) throws Exception {
CountDownLatchTest test = new CountDownLatchTest();
for (int i = 0; i < 3; i++) {
new Thread(test).start();
Thread.currentThread().sleep(200);
}
}
static class CountDownLatchTest implements Runnable{
static CountDownLatch countDownLatch = new CountDownLatch(3);
public void run() {
try {
System.out.println(Thread.currentThread() + " is ready");
countDownLatch.countDown();
countDownLatch.await();
System.out.println(Thread.currentThread() + " is running");
}
catch (Exception e) {
}
}
}
}
输出结果
Thread[Thread-0,5,main] is ready
Thread[Thread-1,5,main] is ready
Thread[Thread-2,5,main] is ready
Thread[Thread-2,5,main] is running
Thread[Thread-0,5,main] is running
Thread[Thread-1,5,main] is running
2 源码分析
CountDownLatch同样也是基于AQS类实现的,对于AQS类不熟悉的,可以参考AbstractQueuedSynchronizer同步器一文。
在CountDownLatch中,state
变量代表latch的数量,当state
> 0时,线程不能通过,当state
= 0时,线程允许通过。
2.1 获取锁
// CountDownLatch的方法
public void await() throws InterruptedException {
// 调用了tryAcquireShared
sync.acquireSharedInterruptibly(1);
}
// 子类辅助方法
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
当state
= 0时,线程允许通过,否则不允许通过。
2.1 释放锁
public void countDown() {
// 调用了tryReleaseShared
sync.releaseShared(1);
}
protected boolean tryReleaseShared(int releases) {
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
调用一次countDown,会将state状态减1,直到将state减到0,则唤醒在排队队列中的线程。
3 总结
- CountDownLatch是一次性的,调用
countDown
函数使它触发后就无法再恢复了 - 当CountDownLatch的
state
变为0后,后续的线程再调用await
函数都能马上获得通行。
转载请注明出处:http://blog.csdn.net/linxdcn/article/details/72857496