【JUC】CountDownLatch/CyclicBarrier/Semaphore

本文深入解析了Java中三种重要的并发控制工具:CountDownLatch、CyclicBarrier和Semaphore的使用场景及区别。通过生动的实例,如值日生关门、集齐龙珠召唤神龙和抢车位,阐述了这些工具如何帮助解决多线程同步问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.CountDownLatch
  • CountDown减法计数,Latch门闩的意思
  • 让一些线程阻塞直到另外一些完成后才被唤醒。
  • 举例:

1,值日生要等所有人走后,才能打扫卫生关灯锁门

  • Demo:
/**
 * 值日生要等所有人走后,才能打扫卫生关灯锁门
 *
 * @author wangjie
 * @version V1.0
 * @date 2019/12/19
 */
public class CountDownLatchDemo1 {

    public static void main(String[] args) throws Exception {
        closeDoor();

    }

    /**
     * 值日生案例
     * @throws InterruptedException
     */
    private static void closeDoor() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t" + "放学离开");
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "\t值日生打扫卫生锁门");
    }
}

-运行结果:
在这里插入图片描述

2.CyclicBarrier
  • 可循环的屏障,让一组线程到达一个屏障时被阻塞,直到最后一个线程到达该屏障,屏障才会开门,所有被屏障拦截的线程才回继续工作。
  • 举例:

集齐七龙珠才能召唤神龙。

  • Demo:
/**
 * 集齐七龙珠才能召唤神龙。
 *
 * @author wangjie
 * @version V1.0
 * @date 2019/12/19
 */
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()->{
            System.out.println("召唤神龙");
        });

        for (int i = 1; i <=7; i++) {
            final int temp = i;
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"\t 收集到第"+ temp +"颗龙珠");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
  • 运行结果:
    在这里插入图片描述
    2.1 CountDownLatch与CyclicBarrier区别

进行下一步动作的动作实施者是不一样的。这里的“动作实施者”有两种,一种是主线程(即执行main函数),另一种是执行任务的其他线程,后面叫这种线程为“其他线程”,区分于主线程。对于CountDownLatch,当计数为0的时候,下一步的动作实施者是main函数;对于CyclicBarrier,下一步动作实施者是“其他线程”。

对于CountDownLatch,其他线程为其他同学,值日生是主线程,在其他同学离开前,值日生是不能关门的。

对于CyclicBarrier,每一个颗龙珠都是一个“其他线程”。当龙珠都集齐后之后,才召唤神龙。而主线程可能早就结束了,这里我们不用管主线程。

在这里插入图片描述

3.Semaphore
  • 信号量两个目的,一个用于多个共享资源的相互排斥,另一个对并发资源数的控制。

  • 举例:

抢车位

  • Demo:
/**
 * 抢车位
 *
 * @author wangjie
 * @version V1.0
 * @date 2019/12/19
 */
public class SemaphoreDemo {
    public static void main(String[] args) {
        //模拟3个停车位
        Semaphore semaphore = new Semaphore(3);
        //模拟6部汽车
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                try {
                    //抢到资源
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "\t抢到车位");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "\t 停3秒离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放资源
                    semaphore.release();
                }
            }, String.valueOf(i)).start();
        }
    }
}
  • 运行结果:
    在这里插入图片描述
    【完】
    :文章内所有测试用例源码:https://gitee.com/wjie2018/test-case.git
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值