【Java8源码分析】并发包-CountDownLatch

转载请注明出处: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值