• CountDownLatch vs CyclicBarrier


    定义

    CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
    CyclicBarrier: A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

    上述是Oracle官方定义。简单来说

    CountDownLatch:计数器,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
    CyclicBarrier:循环屏障,它允许一组线程相互等待以达到一个共同的屏障点。

    区别

    • CountDownLatch 是 AQS (AbstractQueuedSynchronizer) 的一员,但 CyclicBarrier 不是。
    • CountDownLatch 的使用场景中,有两类线程,一类是调用await()方法的等待线程,另一类是调用countDownl() 方法的操作线程。CyclicBarrier 的场景中,只有一类线程,都是相互等待的等待线程。
    • CountDownLatch 是减计数,递减完后不能复位,CyclicBarrier 是加计数,递增完后自动复位

    CountDownLatch 示例

    1. 创建两组线程,一组等待另一组执行完才继续进行
    CountDownLatch countDownLatch = new CountDownLatch(5);
    ExecutorService executorService = Executors.newCachedThreadPool();
    for (int i = 0; i < 5; i++) {
        executorService.execute(() -> {
            countDownLatch.countDown();
            System.out.println("run..");
        });
    }
    for (int i = 0; i < 3; i++) {  //我们要等上面执行完成才继续
        executorService.execute(() -> {
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("await..");
        });
    }
    executorService.shutdown();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    打印:

    run..
    run..
    run..
    run..
    run..
    await..
    await..
    await..
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 等待累加线程执行完,主线程再输出累加结果
    public class ThreadUnsafeExample {
    
        private int cnt = 0;
        
        public void add() {
            cnt++;
        }
    
        public int get() {
            return cnt;
        }
    
        public static void main(String[] args) throws InterruptedException {
            final int threadSize = 1000;
            ThreadUnsafeExample example = new ThreadUnsafeExample();
            final CountDownLatch countDownLatch = new CountDownLatch(threadSize);
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < threadSize; i++) {
                executorService.execute(() -> {
                    example.add();
                    countDownLatch.countDown();
                });
            }
            countDownLatch.await();
            executorService.shutdown();
            System.out.println(example.get());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    打印:

    997
    
    • 1
    • 3 模拟并发
    ExecutorService executorService = Executors.newCachedThreadPool();
            CountDownLatch countDownLatch = new CountDownLatch(1);
            for (int i = 0; i < 5; i++) {
                executorService.submit( () -> {
                    try {
                        countDownLatch.await();
                        System.out.println("【" + Thread.currentThread().getName() + "】开始执行……");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
            }
            Thread.sleep(2000);
            countDownLatch.countDown();//开始并发
            executorService.shutdown();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    打印:

    【pool-2-thread-2】开始执行……
    【pool-2-thread-5】开始执行……
    【pool-2-thread-3】开始执行……
    【pool-2-thread-1】开始执行……
    【pool-2-thread-4】开始执行……
    
    • 1
    • 2
    • 3
    • 4
    • 5

    CyclicBarrier 示例

    • 所有线程相互等待,直到某一步完成后再继续执行
            final int totalThread = 3;
            CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < totalThread; i++) {
                executorService.execute(() -> {
                    System.out.println("before..");
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println("after..");
                });
            }
            executorService.shutdown();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    打印:

    before..
    before..
    before..
    after..
    after..
    after..
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    虹科案例 | ELPRO帮助客户实现符合GDP标准的温度监测和高效的温度数据管理
    使用ElementUI结合Vue完善主页的导航菜单和书籍管理以及后台数据分页查询
    UGUI交互组件InputField
    跨境电商运营:社交媒体营销策略的制定
    基于sass模式Java语言+MySQL + MyCat开发的his系统源码 HIS系统住院业务流程 HIS系统住院流程化管理
    SQL Server对象类型(3)——4.3.视图(View)
    刷题记录(NC15033 小G有一个大树,NC51178 没有上司的舞会)
    为什么别人都不主动联系你
    解读非托管流动性协议Hover: 差异化、层次化的全新借贷体系
    特征工程建模可解释包(note)
  • 原文地址:https://blog.csdn.net/mryang125/article/details/125553912