JUC常用辅助类CountDownLatch、CyclicBarrier、Semaphore

一、CountDownLatch

简介:CountDownLatch倒计时计数锁,其主要有俩个方法,当一个或多个线程调用await()方法时,这些线程会阻塞。

  • 其他线程调用countDown()方法会将计数器减1(调用countDown方法的线程不会阻塞)
  • 当计数器的值变为0时,因await()方法阻塞的线程会被唤醒,继续执行。

在这里插入图片描述

题目:用6个线程模拟6个同学,6个同学全部离开教室,班长线程关门。

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);  //倒计时计算器  初始值为6
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"位同学离开教室");
                countDownLatch.countDown();     //初始值减1
             },String.valueOf(i)).start();
        }
        countDownLatch.await();     //线程阻塞  countDownLatch初始值变为0才被唤醒
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"关门");
         },"班长").start();
    }
}

1位同学离开教室
2位同学离开教室
3位同学离开教室
4位同学离开教室
6位同学离开教室
5位同学离开教室
班长关门

Process finished with exit code 0

main线程执行到countDownLatch.await(); 就会被阻塞,等到
countDownLatch的初始值变为0时才会被唤醒。

二、CyclicBarrier

简介:循环屏障,其实就是加法计算器,到达某个值时,执行某个线程。

题目:收集齐七颗龙族后,自动召唤神龙

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 temi = i;
            new Thread(()->{
                System.out.println("收集第:"+temi+"个龙珠");
                try {
                    cyclicBarrier.await(); //等到7才会被唤醒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

解释:所有线程运行到cyclicBarrier.await()都会被阻塞,等到达7后执行cyclicBarrier中的召唤龙族线程,然后阻塞的线程才会被唤醒继续执行。

三、Semaphore信号量

Semaphore信号量作用:

  • 常用于多个线程抢占多个资源
  • 如果资源类为1,Semaphore等价于synchronized,多个线程抢占一个资源

在信号量上我们定义两种操作:

  • acquire(获取):当一个线程调用acquire操作时,它要么通过成功获取信号量(信号量减1),要么一直等下去,直到有线程释放信号量,或超时。
  • release(释放):实际上会将信号量的值加1,然后唤醒等待的线程
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); //3个资源类  假设是3个车位
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+":抢到了车位");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName()+":离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

1:抢到了车位
3:抢到了车位
2:抢到了车位
2:离开了车位
1:离开了车位
4:抢到了车位
5:抢到了车位
3:离开了车位
6:抢到了车位
5:离开了车位
6:离开了车位
4:离开了车位

只要有线程离开车位就会有线程去抢车位。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值