CountDownLatch CyclicBarrier

CountDownLatch

**
 * 倒计数锁存器
 *
 * 举例:运动员进行跑步比赛时,假设有6个运动员参与比赛,裁判员在终点会为这6个运动员分别计时,
 * 可以想象每当一个运动员到达终点的时候,对于裁判员来说就少了一个计时任务。
 * 直到所有运动员都到达终点了,裁判员的任务也才完成。这6个运动员可以类比成6个线程,
 * 当线程调用CountDownLatch.countDown方法时就会对计数器的值减一,
 * 直到计数器的值为0的时候,裁判员(调用await方法的线程)才能继续往下执行
 */
public class CountDownLatchTest {
    private static CountDownLatch mainCountDown = new CountDownLatch(1);
    // 6个运动员
    private static CountDownLatch playerCountDown = new CountDownLatch(6);


    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        System.out.println("各就各位 预备");
        for (int i = 0; i < 6; i++) {
            executorService.execute(() ->{
                System.out.println(Thread.currentThread().getName() + "运动员等待哨响");
                // 确保所有运动员准备完毕
                try {
                    Thread.sleep(3000);
                    //哨响,开始
                    mainCountDown.await();
                    System.out.println(Thread.currentThread().getName() + "运动员全力冲刺");
                    playerCountDown.countDown();
                    System.out.println(Thread.currentThread().getName() + "到达终点");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        //将executorService转换为ThreadPoolExecutor,ThreadPoolExecutor有方法 getActiveCount()可以得到当前活动线程数
        int threadCount = ((ThreadPoolExecutor)executorService).getActiveCount();
        if (threadCount == 6){
            System.out.println("哨响");
            mainCountDown.countDown();


            //所有线程都到达终点
            playerCountDown.await();
            System.out.println("所有线程都到达终点,比赛结束");
        }
        executorService.shutdown();
    }
}

CyclicBarrier

package com.tgdz.uap;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * ,假设6个线程就相当于6个运动员,到赛道起点时会报数进行统计,如果刚好是6的话,这一波就凑齐了,才能往下执行
 */
public class CyclicBarrierTest {
    //指定必须有6个运动员到达后才能执行
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(6,() -> {
        System.out.println("所有运动员入场,裁判员一声令");
    });

    public static void main(String[] args) {
        System.out.println("运动员准备进场,全场欢呼....");
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        for (int i = 0; i < 6; i++) {
            executorService.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + "运动员,进场");
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName() + "运动员出发");
                } catch (Exception e) {
                    e.printStackTrace();
                }

            });

        }
    }
}

CyclicBarrier 图解
在这里插入图片描述
CyclicBarrier在使用一次后,下面依然有效,可以继续当做计数器使用,这是与CountDownLatch的区别之一

CountDownLatch应用场景:假如有多个sheet,开启多个线程解析sheet等待所有线程解析完毕唤醒主线程响应解析完毕
CyclicBarrier应用场景:假如有多个sheet每sheet中保存不同厂家的年销售数据,开启多个线程解析sheet,解析完后再进行汇总处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会跑的葫芦怪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值