<返回更多

多线程中countDownLatch的使用

2020-07-28    
加入收藏

举例:火箭发射倒计时

一、定义

countDownLatch从字面上理解,countDown倒计时的意思latch是锁、门栓的意思,那么countDownLatch就是倒计时的门栓。

JDK1.5中提供了JAVA.util.concurrent.CountDownLatch类,用于一个或多个类等待一直到其他线程完成一系列操作。

CountDownLatch创建时设置一个count值,表示倒计时的次数,然后等待状态的线程调用CountDownLatch的await()方法进行等待,倒计时的方法是countDown(), 每次countDown都会减少count的值,直到count为0,则所有的await()的线程都会从等待中返回。

二、使用

我们使用员工下班值班人员锁门案例进行演示

for (int i=1;i<=6;i++){

new Thread(() -> {

System.out.println("第"+Thread.currentThread().getName()+"t 位员工离开房间");

},String.valueOf(i)).start();

}

System.out.println(Thread.currentThread().getName()+"t 值班人员最后关门走人");

如果我们不使用CountDownLatch 这样就会导致员工还没有全部离开房间,这个时候管理员把门锁上。

运行结果

多线程中countDownLatch的使用

没有使用CountDownLatch 运行结果

使用CountDownLatch代码如下

CountDownLatch countDownLatch = new CountDownLatch(6);for (int i=1;i<=6;i++){
    new Thread(() -> {
        System.out.println("第"+Thread.currentThread().getName()+"t 位员工离开房间");        countDownLatch.countDown();    },String.valueOf(i)).start();}
countDownLatch.await();System.out.println(Thread.currentThread().getName()+"t 值班人员最后关门走人");

运行结果:

多线程中countDownLatch的使用

使用CountDownLatch运行结果

三、原理

在上面我们看到,CountDownLatch主要使用CountDown方法进行减1的操作,使用await方法进行等到操作。

1、CountDown原理

多线程中countDownLatch的使用

 

CountDownLatch里面保存了一个count值,通过减1操作,直到为0时候,等待线程才可以执行。而且通过源码也可以看到这个countDown方法其实是通过sync调用releaseShared(1)来完成的。

sync是个什么,releaseShared方法又是如何实现的。我们不妨接着看源码,在CountDownLatch的开头我们找到了答案,原来这个sync在这里定义了。

多线程中countDownLatch的使用

 

在这里我们发现继承了AbstractQueuedSynchronizer(AQS)。AQS的其中一个作用就是维护线程状态和获取释放锁。在这里也就是说CountDownLatch使用AQS机制维护锁状态。而releaseShared(1)方法就是释放了一个共享锁。

现在理解了吧,底层使用AQS机制调用releaseShared方法释放一个锁资源。

那么等待的方法是如何实现的呢?

2、await原理

多线程中countDownLatch的使用

 


多线程中countDownLatch的使用

 

这两个方法都是让线程等待,一个有时间限制、一个没有时间限制

await()方法底层主要是显示acquireSharedInterruptibly()方法来实现的

多线程中countDownLatch的使用

 

首先acquireSharedInterruptibly方法里面有两个if语句,第一个判断是否被中断,如果被中断了,那就抛出中断异常,然后判断是否还有线程未执行,如果有那就执行。

tryAcquireShared方法就是判断countDown是否减到了0,如果到了0,那就返回1,不需要等待,如果没有到0 说明还有未执行的线程,继续等待所有线程执行结束

doAcquireSharedInterruptibly方法是如何实现的

多线程中countDownLatch的使用

 

大致意思我可以描述一下,他会用一个一个的节点将线程串起来 等达到条件后再一个一个的唤醒。核心就是第三行的addWaiter函数。我们可以再跟进去看看吧。

多线程中countDownLatch的使用

 

这里面使用cas机制。

对于CountDownLatch来说原理主要还是通过源码来认识。不过CountDownLatch看起来虽然很好用,也有很多不足之处,比如说CountDownLatch是一次性的 , 计数器的值只能在构造方法中初始化一次 , 之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后 , 它不能再次被使用。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>