面试官: CountDownLatch有了解过吗?说说看(源码剖析)

前言

目前正在出一个Java多线程专题长期系列教程,从入门到进阶含源码解读, 篇幅会较多, 喜欢的话,给个关注❤️ ~

Java提供了一些非常好用的并发工具类,不需要我们重复造轮子,本节我们讲解CountDownLatch,一起来看下吧~

CountDownLatch

首先我们来看下这玩意是干啥用的。CountDownLatch同样的也是java.util.concurrent并发包下的工具类,通常我们会叫它是并发计数器,这个计数不是记12345,主要的使用场景是当一个任务被拆分成多个子任务时,需要等待子任务全部完成后,不然会阻塞线程,每完成一个任务计数器会-1,直到0。这个有点类似go语言中的sync.WaitGroup

废话不多说,我们通过例子带大家快速入门, 在这之前,还需给大家补充一下它的常用方法~

  • public CountDownLatch(int count) {...} 构造函数

  • void await() 是当前线程等待直到锁存储器计到0,或者线程被中断

  • boolean await(long timeout, TimeUnit unit) 是当前线程等待直到锁存储器计到0,或者线程被中断, 如果为0返回true, 可以指定等待的超时时间

  • countDown() 递减锁存器的计数,如果到0则释放所有等待的线程`

  • getCount() 获取锁存器的计数

下面我们看下具体的使用:

 private void doAcquireSharedInterruptibly(int arg)
    throws InterruptedException 
{
    // 以共享模式添加到等待队列    
    final Node node = addWaiter(Node.SHARED);
    boolean failed = true;
    try {
        for (;;) {
            // 返回前一个节点
            final Node p = node.predecessor();
            if (p == head) {
                int r = tryAcquireShared(arg);

                if (r >= 0) {
                    setHeadAndPropagate(node, r);
                    p.next = null;
                    failed = false;
                    return;
                }
            }
            // 检查并更新未能获取的节点的状态。如果线程应该阻塞,则返回 true
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                throw new InterruptedException();
        }
    } finally {
        // 失败就取消
        if (failed)
            cancelAcquire(node);
    }
}

结束语

下节给大家讲下CyclicBarrier,跟CountDownLatch有点类似 ~


往期内容推荐

项目源码(源码已更新 欢迎star⭐️)

  • java-thread-all

  • 地址: https://github.com/qiuChengleiy/java-thread-all.git

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)


本篇文章来源于微信公众号: 程序员皮卡秋



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2023-06-27