Java基础 -> CountDownLatch丶CyclicBarraer和Semaphore的区别和底层原理

CountDownLatch丶CyclicBarraer和Semaphore的区别和底层原理

CountDownLatch表示计数器,可以给CountDownLatch设置⼀个数字,CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信

  • 从名字可以猜出,是做数量减法的一种机制

  • CountDownLatch能够使线程等待另外一些线程完成各自工作之后,再继续执行。

    • 另外的线程每执行完一个计数器就减一
  • 调⽤await()⽅法阻塞线程,是利⽤AQS排队,加入阻塞队列

  • 其他线程可以调⽤CountDownLatch的countDown()⽅法来对 CountDownLatch(计数器)中的数字减⼀

  • 当数字被减成0后,所有await阻塞的线程都将被唤醒。

    • 例如一些核心组件线程和我们的工作线程
    • 我们可以把我们的工作线程用**await()**方法加入到阻塞队列中
    • 然后先执行依赖的核心组件线程,每执行完成一个计数器减一
    • 直到减完了,我们的工作线程就会被队列以先进先出的方式全部唤醒,正常执行
//定义一个计数器,计数器参数表示在计数器阻塞线程执行之前该有多少线程执行
CountDownLatch countDownLatch = new CountDownLatch(2);
//第一个线程
new Thread(() -> {
    //计数器减一,如果计数器为0,则释放所有阻塞线程
    countDownLatch.countDown();
}).start();
//第二个线程
new Thread(() -> {
 	//计数器减一,如果计数器为0,则释放所有阻塞线程
    countDownLatch.countDown();
}).start();
//当前线程加入阻塞队列
countDownLatch.await();

相对的还有一个CyclicBarraer

  • CyclicBarraer可以使一组线程等待,当线程数量够时,一起执行
  • 利用await()阻塞,每次阻塞一个线程并且计数变量减一
  • 当计数变量为0时,将之前阻塞的线程都一起唤醒
    • 当阻塞的线程达到了规定的数量的时候就一起释放
CyclicBarrier barrier = new CyclicBarrier(3, () -> {...});
for (int i = 0; i < 3; i++) {
    new Thread(() -> {
 	//将此线程阻塞并计数器减一,如果计数器为0,则释放所有刚刚阻塞线程
    barrier.await();
	}).start();
}

CountDownLatch是先执行前置的线程,再执行任务线程

CyclicBarraer是指定一定数量的线程在某一刻一起执行

Semaphore表示信号量,Semaphore可以控制同时访问的线程个数

  • 通过acquire()来获取许可,如果没有许可可⽤则线程阻塞,并通过AQS来排队
    • 许可就是判断同时访问的线程有没有超过指定的限制
    • 如果同时访问的线程过多,则将申请的线程加入阻塞队列
    • 这是一种共享锁,AQS的state变量记录的是共享锁的数量
    • 不再是独占锁那样,记录的是0还是大于0去判断是否上锁
  • 可以通过release()⽅法来释放许可,当某个线程执行完释放了某个许可后,会从AQS中正在排队的第⼀个线程开始依次唤醒,直到没有空闲许可
    • 释放许可就是表示可以使多余的线程执行
//同时访问的线程个数 state=2
private static Semaphore semaphore = new Semaphore(2);
for (int i = 0; i < 5; i++) {
    new Thread(() -> {
        try {
            // 获取令牌尝试进入
            semaphore.acquire();
            // 释放令牌
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CountDownLatchCyclicBarrier、Semaphore都是Java中用于多线程编程的同步工具类,但它们有不同的作用和使用场景。 1. CountDownLatch CountDownLatch(倒计时门闩)是一个同步工具类,它允许一个或多个线程等待其他线程完成操作后再继续执行。CountDownLatch维护了一个计数器,初始值为线程数量,线程完成任务后计数器减1。当计数器为0时,等待线程继续执行。CountDownLatch的主要方法是await()和countDown()。 使用场景:CountDownLatch适用于一组线程等待另一组线程完成操作后再继续执行的场景。比如,主线程等待所有子线程完成初始化后再继续执行。 2. CyclicBarrier CyclicBarrier(循环屏障)是一个同步工具类,它允许一组线程相互等待,直到所有线程都到达某个屏障点后再继续执行。CyclicBarrier的主要方法是await()。 使用场景:CyclicBarrier适用于需要多个线程协同完成某个任务的场景。比如,多个线程同时执行某个操作,需要等待所有线程都执行完后再进行下一步操作。 3. Semaphore Semaphore(信号量)是一个同步工具类,它允许多个线程同时访问某个资源。Semaphore维护了一个许可证数量,线程需要先获取许可证才能访问资源,访问完后释放许可证。Semaphore的主要方法是acquire()和release()。 使用场景:Semaphore适用于需要限制线程数量访问某个资源的场景。比如,数据库连接池限制同时访问连接的线程数量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值