并发编程:并发工具的使用及原理

Condition

condition.await() ---> aqs.await():1、先addConditionWaiter(),把当前节点加入到Condition队列中(等待队列),waitStatus=-2,这个入队的流程和AQS有些类似,但是这里没有空的头结点,入队的线程节点自身就是头结点,而且是单向链表。2、fullyRelease,看方法名就是全部释放锁,意思就是重入次数全部释放。然后去唤醒AQS中head.next节点(唤醒 != 拿到锁,可能会被插队)。
condition.await() ---> aqs.signal():1、将等待队列Node的waitStatus改成0,再加到AQS阻塞队列中,再把原节点移除,Node加入到AQS以后,需要进行acquireQueued()操作,该操作会尝试去获取锁,获取不到锁后会将前置节点的状态置为SIGNAL,然后挂起。

CountDownLatch

计数器,发令枪。核心方法是await()和countDown()。
基于共享锁实现,底层还是addWaiter(),创建status为SHARED进入AQS队列。然后节点都会在AQS阻塞,当countDown()使得state(锁次数)变为0时,会从头节点开始挨个唤醒AQS队列中的线程。

Semaphore

限流工具,也分公平和非公平。构造参数permits代表令牌,线程会去获取令牌,假如获取失败就会进入阻塞状态。state表示令牌数,也是基于共享锁的实现。假如令牌数不够了,进入AQS队列等待,唤醒时会还回一个令牌。公平和非公平的区别类似于普通的锁,非公平锁会出现插队情况,公平锁不会。

CyclicBarrier

栅栏,使一组线程到达共享点之前阻塞。当await()次数到达 构造参数 parties时,开始后面的逻辑。当parties到达目标值后会开启新的循环,重新等await()减到0。

posted @ 2020-07-12 20:10  挣扎一下  阅读(149)  评论(0编辑  收藏  举报