CountDownLatch原理
CountDownLatch是使用一组线程来等待其它线程执行完成,这个场景类似于一群人考试,先做的人先交了,但是在考试时间没到的前提下,老师必须额等待最后一个学生完成交卷老师才能走,CountDownLatch使用Sync继承AQS。构造函数很简单地传递计数值给Sync,并且设置了state,这个state的值就是倒计时的数值,每当一个线程完成了自己的任务(学生完成交卷),那么就使用CountDownLatch.countdown()方法来做一次state的减一操作,在内部是通过CAS完成这个更新操作,直到所有的线程执行完毕,也就是说计数值变成0,那么就然后在闭锁上等待的线程就可以恢复执行任务。
CyclicBarrier原理 栅栏
CyclicBarrier 的字面意思是可循环(Cyclic)使用的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。线程进入屏障通过CyclicBarrier的await()方法。
实现原理:在CyclicBarrier的内部定义了一个Lock对象,其实就是ReenTrantLock对象,每当一个线程调用CyclicBarrier的await方法时,将剩余拦截的线程数减1,然后判断剩余拦截数是否为0,如果不是,进入Lock对象的条件队列等待。如果是,执行barrierAction对象的Runnable方法,然后将锁的条件队列中的所有线程放入锁等待队列中,这些线程会依次的获取锁、释放锁,接着先从await方法返回,再从CyclicBarrier的await方法中返回。
其中await方法:
1.获取lock对象,然后拦截数减一,直到拦截数为0,结束await
2.出现中断,结束栅栏然后退出
3.超时也可以退出栅栏
CyclicBarrier和CountDownLatch的区别
1.CountDownLatch 可以说成一个或者一组线程1等待其它线程执行完毕,重点是每当一个线程的countdown减一的时候,是其中的一个线程执行完了一个任务,可以类比成大家一起考试,有的人提前交卷了,而老师还是不能走,因为还有人没做完,得等全部人做完才行;
而CyclicBarrier则是一组线程互相等待,只有全部到达了栅栏点以后才能继续执行;这个可以类比成上车,只有乘客把车上的位置占用完了以后,车才能开始,也就是大家都在等位置坐满,并不是说有一个人坐上车(到栅栏点),这个人就可以坐公交车走了,这个人心里也清楚得等车上的位置坐满车才能走,大家心里默认是互相等待车完全坐满,也就是前面说的一组线程互相等待的意思
2.CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
3.CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。比如以下代码执行完之后会返回true。