(本文是学习Java3y文章所记录下来的知识点)
CountDownLatch和CyclicBarrier都是线程同步的工具类。
两者等待的主体不一样:
CountDownLatch允许一个或多个线程一直等待,直至这些线程完成他们的操作。
CyclicBarrier是当线程达到某一状态后,暂停等待其他线程均达到这个状态后,才继续执行。
CountDownLatch通常是主线程/调用线程调用await()
CyclicBarrier是任务线程调用await(),CyclicBarrier阻塞的是任务线程,不影响主线程。
CountDownLatch和CyclicBarrier都是基于AQS实现的。
1.CountDownLatch
在构建CountDownLatch对象时,传入的值会赋值给AQS的关键变量state。执行countDown()就是利用CAS将state-1;执行await()就是判断state是否为0,不为0将当前线程加入到对列中,即阻塞线程。头节点一直自旋等待state为0,当state为0时,头节点把剩余在队列中阻塞的节点唤醒(释放所有等待的线程)。
2.CyclicBarrier
它不像CountDownLatch和ReentrantLock(重入锁)使用AQS的state变量,它直接借助ReentrantLock加上Condition等待唤醒的功能实现。自身维护count和parties两个变量。
在构建CyclicBarrier时,传入的值会赋值给CyclicBarrier内部维护的count变量,也会赋值给parties变量(可复用的关键所在)。
每次调用await()时,会将count-1,这里操作count值使用ReentrantLock来保证线程安全。如果count不为0,添加线程至condition队列中;若count为0时,把节点从condition队列添加到AQS队列中,全部唤醒,并将parties的值重新赋值为count(复用的原理)
(后期撸过源码继续更新)
网友评论