这两天写多线程时,用到了CyclicBarrier,下意识的认为CyclicBarrier和CountDownLatch作用很像,就翻阅资料查了一下,说一下他们的区别吧
CyclicBarrier和CountDownLatch 都位于java.util.concurrent 这个包下
| CountDownLatch | CyclicBarrier |
| 减计数方式 | 加计数方式 |
| 计算为0时释放所有等待的线程 | 计数达到指定值时释放所有等待线程 |
| 计数为0时,无法重置 | 计数达到指定值时,计数置为0重新开始 |
| 调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 | 调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞 |
| 不可重复利用 | 可重复利用 |
一、CountDownLatch用法
CountDownLatch类只提供了一个构造器:
- public CountDownLatch(int count) { };
然后下面这3个方法是CountDownLatch类中最重要的方法:
- public void await() throws InterruptedException { };
- public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
- public void countDown() { };
CountDownLatch, 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
下面举个例子说明:
- package main.java.CountDownLatch;
-
- import java.util.concurrent.CountDownLatch;
-
-
-
-
-
-
- public class countDownlatchTest {
- public static void main(String[] args) throws InterruptedException {
- CountDownLatch countDownLatch = new CountDownLatch(5);
- for(int i=0;i<5;i++){
- new Thread(new readNum(i,countDownLatch)).start();
- }
- countDownLatch.await();
- System.out.println("线程执行结束。。。。");
- }
-
- static class readNum implements Runnable{
- private int id;
- private CountDownLatch latch;
- public readNum(int id,CountDownLatch latch){
- this.id = id;
- this.latch = latch;
- }
- @Override
- public void run() {
- synchronized (this){
- System.out.println("id:"+id);
- latch.countDown();
- System.out.println("线程组任务"+id+"结束,其他任务继续");
- }
- }
- }
- }
输出结果:
id:1
线程组任务1结束,其他任务继续
id:0
线程组任务0结束,其他任务继续
id:2
线程组任务2结束,其他任务继续
id:3
线程组任务3结束,其他任务继续
id:4
线程组任务4结束,其他任务继续
线程执行结束。。。。
线程在countDown()之后,会继续执行自己的任务,而CyclicBarrier会在所有线程任务结束之后,才会进行后续任务,具体可以看下面例子。
二、CyclicBarrier用法
CyclicBarrier提供2个构造器:
- public CyclicBarrier(int parties, Runnable barrierAction) {
- }
-
- public CyclicBarrier(int parties) {
- }
参数parties指让多少个线程或者任务等待至barrier状态;参数barrierAction为当这些线程都达到barrier状态时会执行的内容。
CyclicBarrier中最重要的方法就是await方法
- public int await() throws InterruptedException, BrokenBarrierException { };
- public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };
举例说明
- package main.java.countOff;
-
- import java.util.concurrent.CyclicBarrier;
-
-
-
-
-
-
- public class cyclicBarrierTest {
- public static void main(String[] args) throws InterruptedException {
- CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
- @Override
- public void run() {
- System.out.println("线程组执行结束");
- }
- });
- for (int i = 0; i < 5; i++) {
- new Thread(new readNum(i,cyclicBarrier)).start();
- }
-
-
-
-
-
- }
- static class readNum implements Runnable{
- private int id;
- private CyclicBarrier cyc;
- public readNum(int id,CyclicBarrier cyc){
- this.id = id;
- this.cyc = cyc;
- }
- @Override
- public void run() {
- synchronized (this){
- System.out.println("id:"+id);
- try {
- cyc.await();
- System.out.println("线程组任务" + id + "结束,其他任务继续");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
输出结果:
id:1
id:2
id:4
id:0
id:3
线程组执行结束
线程组任务3结束,其他任务继续
线程组任务1结束,其他任务继续
线程组任务4结束,其他任务继续
线程组任务0结束,其他任务继续
线程组任务2结束,其他任务继续