• 【JUC的三个⼯具类】CountDownLatch 、CyclicBarrier 、Semaphore_JUC17


    前言:为什么这⾥要介绍下JUC强⼤的⼯具类?

    • 因为他们三个CountDownLatch | CyclicBarrier | Semaphore 底层都是AQS来实现的

    1、CountDownLatch(闭锁) 做减法

    1)什么是CountDownLatch?

    帮助理解:秦国一统六国(六国一一被灭,秦国完成统一)

    • ①. CountDownLatch主要有两个⽅法(countDown()、await()),当⼀个或多个线程调⽤await⽅法时,这些线程会阻塞
    • ②. 其它线程调⽤countDown⽅法会将计数器减1调⽤countDown⽅法的线程不会阻塞)。
    • ③. 计数器的值变为0时,因await⽅法阻塞的线程会被唤醒,继续执⾏。
    2)代码实践
    //需求:要求6个线程都执行完了,mian线程最后执行
    public class CountDownLatchDemo {
        public static void main(String[] args) throws Exception{
    
            CountDownLatch countDownLatch=new CountDownLatch(6);
            for (int i = 1; i <=6; i++) {
                new Thread(()->{
                    System.out.println(Thread.currentThread().getName()+"\t");
                    countDownLatch.countDown();
                },i+"").start();
            }
            countDownLatch.await();
            System.out.println(Thread.currentThread().getName()+"\t班长关门走人,main线程是班长");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2、CyclicBarrier做加法

    1)什么是CyclicBarrier?

    帮助理解:集齐7颗龙珠才能召唤神龙

    • CyclicBarrier的字⾯意思是可循环(Cyclic) 使⽤的屏障(barrier)
    • 它要做的事情是,让⼀组线程到达⼀个屏障(也可以叫做同步点)时被阻塞直到最后⼀个线程到达屏障时,屏障才会开⻔,所有被屏障拦截的线程才会继续⼲活,线程进⼊屏障通过CyclicBarrier的await()⽅法。
    2)代码验证:
    //集齐7颗龙珠就能召唤神龙
    public class CyclicBarrierDemo {
        public static void main(String[] args) {
            // public CyclicBarrier(int parties, Runnable barrierAction) {}
            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();
                    }
                }).start();
            }
    
        }
    }
    
    
    • 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

    3、Semaphore 信号量

    1)什么是Semaphore?

    帮助理解:抢车位(七辆车抢四个车位,抢不到的阻塞。有车走了,阻塞的车可以继续抢)

    • ①. acquire(获取):当⼀个线程调⽤acquire操作时,它要么通过成功获取信号量(信号量减1)要么阻塞,直到有线程释放信号量,或超时。
    • ②. release(释放):实际上会将信号量的值加1,然后唤醒等待的线程
    • ③. 信号量主要⽤于两个⽬的:⼀个是1. ⽤于多个共享资源的互斥使⽤,另⼀个2. ⽤于并发线程数的控制
    2)代码验证:
    public class SemaphoreDemo {
        public static void main(String[] args) {
            Semaphore semaphore=new Semaphore(3);
            for (int i = 1; i <=6; i++) {
                new Thread(()->{
                    try {
                        System.out.println(Thread.currentThread().getName()+"\t抢占了车位");
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName()+"\t离开了车位");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        semaphore.release();
                    }
                }String.valueOf(i)).start();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

  • 相关阅读:
    停止像这样使用 “async/await“,改用原版
    MFC Windows 程序设计[132]之打开按钮的启用与禁用
    Python中的依赖注入
    怎么用CSS画一个爱心?
    带你一起玩转Redis 的 List 数据类型
    股票业绩预测:实战 iwencai JS逆向 + 数据采集(20220803)
    jeecg-boot集成xxl-job调度平台,每秒/每分钟/手动都能执行成功,但是设置固定时间不触发?
    数据分析实战 | 多元回归——广告收入数据分析
    MacOS 中Boost的安装和使用
    C++项目:高并发内存池
  • 原文地址:https://blog.csdn.net/weixin_38963649/article/details/126144408