zoukankan      html  css  js  c++  java
  • iv005-CountDownLatch,CyclicBarrier,Semaphore

    1.CountDownLatch

    让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。
    CountDownLatch主要有两个方法,当一个或多个线程调用await()方法时,调用线程会被阻塞。其它线程调用countDown()方法会将计数器减1(调用countDown方法的线程不会阻塞),当计数器的值变为零时,因调用await方法被阻塞的线程会被唤醒,继续执行。
    示例代码:

    public class CountDownLatchDemo {
    
        public static void main(String[] args) {
            int size = 10;
            CountDownLatch countDownLatch = new CountDownLatch(size);
            for (int i = 1; i <= size; i++) {
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName() + "	 离开教室");
                    //做减法
                    countDownLatch.countDown();
                }, i + "").start();
            }
            try {
                //阻塞等到countDownLatch为0
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println(Thread.currentThread().getName() + "	 班长锁门");
        }
    }
    

    运行结果:

    1	 离开教室
    4	 离开教室
    3	 离开教室
    2	 离开教室
    6	 离开教室
    5	 离开教室
    7	 离开教室
    8	 离开教室
    9	 离开教室
    10	 离开教室
    main	 班长锁门
    

    2.CyclicBarrier

    CyclicBarrier的字面意思是可循环(Cyclic)使用的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。
    示例代码:

    public class CyclicBarrierDemo {
    
        public static void main(String[] args) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
                System.out.println("集齐7颗龙珠 开始召唤神龙");
            });
    
            for (int i = 1; i <= 7; i++) {
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName() + "	 号龙珠准备好了");
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "	 号龙珠启动");
                }, i + "").start();
            }
        }
    }
    

    运行结果:

    1	 号龙珠准备好了
    5	 号龙珠准备好了
    4	 号龙珠准备好了
    3	 号龙珠准备好了
    2	 号龙珠准备好了
    7	 号龙珠准备好了
    6	 号龙珠准备好了
    集齐7颗龙珠 开始召唤神龙
    6	 号龙珠启动
    4	 号龙珠启动
    7	 号龙珠启动
    2	 号龙珠启动
    3	 号龙珠启动
    5	 号龙珠启动
    1	 号龙珠启动
    

    3.Semaphore

    信号量主要用于两个目的,一个是用于多个共享资源的互斥作用,另外一个用于并发线程数的控制。
    示例代码:

    public class SemaphoreDemo {
    
        public static void main(String[] args) {
    
            //模拟三个车位
            Semaphore semaphore = new Semaphore(3);
    
            //控制6辆车同时抢车位
            CountDownLatch countDownLatch = new CountDownLatch(6);
    
            //模拟6辆车抢车位
            for (int i = 1; i <= 6; i++) {
                new Thread(() -> {
                    countDownLatch.countDown();
                    try {
                        countDownLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "	 开始抢车位");
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName() + "	 抢到车位");
                        TimeUnit.SECONDS.sleep(3);
                        System.out.println(Thread.currentThread().getName() + "	 停车3秒离开");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        semaphore.release();
                    }
                }, i + "").start();
            }
        }
    }
    

    运行结果:

    1	 开始抢车位
    3	 开始抢车位
    5	 开始抢车位
    4	 开始抢车位
    6	 开始抢车位
    2	 开始抢车位
    5	 抢到车位
    3	 抢到车位
    1	 抢到车位
    3	 停车3秒离开
    1	 停车3秒离开
    4	 抢到车位
    5	 停车3秒离开
    6	 抢到车位
    2	 抢到车位
    4	 停车3秒离开
    6	 停车3秒离开
    2	 停车3秒离开
    
  • 相关阅读:
    Vue 移动端向上滑动加载
    关于NPOI 判断Office 是否为空的操作
    定时任务的处理
    Web中线程与IIS线程池自动回收机制
    本地VS调试服务器 IIS 程序
    每天学点node系列-stream
    聊聊前端模块化开发
    位运算解决多标签问题【原创】
    <未来世界的幸存者> 读后感(现实篇和职业篇)【原创】
    Nest.js你学不会系列-初识Nest
  • 原文地址:https://www.cnblogs.com/everyingo/p/14554278.html
Copyright © 2011-2022 走看看