辅助类,CountDownLatch,CyclicBarrier,Semaphore(信号标; 旗语)

CountDownLatch减法计数器演示
public static void main(String[] args) throws InterruptedException {
        // 减法计数器, 构造器传入初始的计数值
        CountDownLatch countDownLatch = new CountDownLatch(6);
        // 模拟7个人,6个学生,1个看门大爷,直到六个学生全部出去,再关门
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "出去了");
                countDownLatch.countDown();
                System.out.println("ss");
            }, String.valueOf(i)).start();

        }
        // 这个方法的作用: 等待计数器变为0,countDownLatch.await() 唤醒,再往下执行
        countDownLatch.await();
        System.out.println("close door");
    }

辅助类,CountDownLatch,CyclicBarrier,Semaphore(信号标; 旗语)

CyclicBarrier演示
public static void main(String[] args) {
        // 加法计数器,集齐七颗龙珠召唤神龙
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println("成功召唤神龙!!");
        });

        for (int i = 0; i < 7; i++) {
            // 注意这里直接访问i是访问不到的,因为new了一个对象
            // 需要一个常量值来作为临时i的替换,再访问
            // 当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。
            final int temp = i + 1;
            new Thread(() -> {
                System.out.printf("集齐了%d颗龙珠\n", temp);
                // 等待七个线程全部开启,再唤醒
                try {
                    // 调用了await后,内部会自动加1,直到计数到7就会唤醒,继续往下执行
                    cyclicBarrier.await();
                    System.out.println("ss");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

辅助类,CountDownLatch,CyclicBarrier,Semaphore(信号标; 旗语)

Semaphore演示
public static void main(String[] args) {
        /**
         * 信号量
         * 原理:
         *      acquire(): 获取,如果没有可获取的资源了,等待,等待直到被释放
         *      release(): 释放,会将当前的信号量释放,然后唤醒等待的线程
         * 实例: 3个停车位,6辆车
         * 作用: 多个共享资源互斥的使用,并发限流,控制最大的线程数
         * 应用: 网络限流
         */
        Semaphore semaphore = new Semaphore(3);
        // 开启6个线程,相当于6辆车
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {

                try {
                    // 获取车位
                    // System.out.println(Thread.currentThread().getName()+"开始寻求车位");
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "获得了车位!!!");
                    // 停车2s
                    TimeUnit.SECONDS.sleep(12);
                    System.out.println(Thread.currentThread().getName() + "离开了车位!!!");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    // 释放车位
                    semaphore.release();

                }
            }, String.valueOf(i)).start();
        }
    }

辅助类,CountDownLatch,CyclicBarrier,Semaphore(信号标; 旗语)

上一篇:Semaphore学习


下一篇:Semaphore -信号量、实现限流