AQS之countDownLatch源码分析

  • 介绍

        CountDownLatch(闭锁)是一个同步协助类,允许一个或多个线程等待,直到其他线程完成操作集。

  • 代码准备
    • 让多个线程等待一个线程执行
public class CountDownLatchTest1 {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        for(int i=0;i<5;i++){
            new Thread(()->{
                try {
                    countDownLatch.await();
                    String parter = "【" + Thread.currentThread().getName() + "】";
                    System.out.println(parter + "开始执行……");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

        Thread.sleep(2000);
        System.out.println("等待");
        countDownLatch.countDown();
    }
}

 

 

  •         让一个线程等待多个线程执行
public class CountDownLatchTest2 {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for(int i=0;i<5;i++){
            final int index =i;
            new Thread(()->{
                try {
                    Thread.sleep(1000 +
                            ThreadLocalRandom.current().nextInt(1000));
                    System.out.println(Thread.currentThread().getName()
                            + " finish task" + index);

                    countDownLatch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

        System.out.println("主线程等待");
        countDownLatch.await();
        System.out.println("主线程:在所有任务运行完成后,进行结果汇总");
    }
}

  • 源码分析

         进入await()方法发现acquireSharedInterruptibly()方法是传入固定参数1。

 

        

         又是AQS这块熟悉的代码,先是try尝试,然后是do进行一些列入队和阻塞操作。从这个方法我们可以看到countDownLatch是共享锁。

        闭锁的try方法相当简单,其state为我们创建闭锁时传入的值。返回-1,进入我们AQS的doAcquireSharedInterruptibly()方法中进行入队和阻塞。

        闭锁的countDown()方法也是我们常见到的releaseShared,且固定传1 

        其中doReleaseShared()方法为AQS共用的解锁方法,可参考semaphore。我们需要看一下tryReleaseShared()方法在countDownLatch中是如何实现的。

 

         可见每次闭锁每次countdown就会将state减一,当state为0时就会唤醒线程。

  • 总结
    1. 我们可以看到在reentrantlock中state属性为重入次数,但是在semaphore中可以理解为资源量,在countDownLatch中可以理解为计数器可知道。独占锁是可以重入的,而共享锁是不支持重入的。
    2. 我们看到countDownLatch作用比较类似join()方法。但是闭锁相对于join来说会更灵活,它既可以在n个线程里进行countDown操作,也可以在一个线程里进行n此countDown操作。而join的实现原理是不停的检查join的线程是否存活,如果join线程存活则会让当前线程永远等待。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值