CountDownLatch与CyclicBarrier

CountDownLatch

CountDownLatch通过计数器来实现,计数器表示线程的数量。每当一个线程执行结束后,计数器的值就会减1,并在await方法处阻塞。一旦计数器为0,所有阻塞的线程均被释放,await方法后所有后续动作都会开始执行。计数器无法被重置。

模拟等班级的5位同学都离开教室后,老师才关灯锁门

1
2
3
4
5
6
7
8
9
10
11
12
13
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                System.out.println("第" + Thread.currentThread().getName() + "号同学离开教室");
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println("所有同学都离开教室了,老师关灯锁门");
    }
}

控制台输出如下:

 

1
2
3
4
5
6
1号同学离开教室
4号同学离开教室
3号同学离开教室
2号同学离开教室
5号同学离开教室
所有同学都离开教室了,老师关灯锁门

 

观察到线程countDownLatch.countDown()方法后阻塞在await方法处,当所有线程都执行countDownLatch.countDown()方法后,即计数器count减为0后,每个线程的await()方法就会立刻return,从而执行之后的方法

CyclicBarrier

CyclicBarrier可以协同多个线程,每个线程到达这个屏障处时都会等待,直到所有线程都到达了这个屏障时,再一起继续执行后面的动作。

 

用多线程结合CyclicBarrier模拟等5个人都到齐后再开会

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
            System.out.println("*******人员到齐开始开会");
        });
        for (int i = 1; i <= 5; i++) {
            final int finalI = i;
            new Thread(() -> {
                System.out.println("第" + finalI + "号人员到达");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }
}

 

 控制台输出如下:

 

1
2
3
4
5
6
1号人员到达
4号人员到达
5号人员到达
3号人员到达
2号人员到达
*******人员到齐开始开会

 综上:

1.CountDownLatch本质是一个计数器,线程执行一次,计数器减一,只能单次使用;而CyclicBarrier类似阀门或者栅栏,需要所有线程都到达,然后才能继续执行,可以多次使用

2.CountDownLatch当调用countDown()方法后的计数器等于指定的线程数之后,可以唤起多个线程的任务;而CyclicBarrier当执行到await()方法的线程数量等于指定的parties数量之后,只能唤起一个BarrierAction
3.CountDownLatch相当于是“i--”,而CyclicBarrier相当于是“i++”
 
 
 
 
posted @   达摩克利斯之剑  阅读(173)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示