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秒离开
    
  • 相关阅读:
    嵌入式Linux c语言常用数据结构
    Project Euler 9
    串口应用开发的步骤
    创建简单的守护进程的编写规则
    Linux进程间通信信号通信
    [转]linux进程间的通信手段
    守护进程实例
    Linux slab 分配器剖析了解 Linux 内存管理的方式(转)
    嵌入式Linux c语言常用数据结构2
    嵌入式程序员应知道的几个题目(重要)
  • 原文地址:https://www.cnblogs.com/everyingo/p/14554278.html
Copyright © 2011-2022 走看看