zoukankan      html  css  js  c++  java
  • java并发编程之并发工具类CountDownLatch,CyclicBarrier,Semaphore详解(转)

    1 前言

    在JDK的并发包里提供了几个非常有用的并发工具类。CountDownLatch、CyclicBarrier和 Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程间交换数 据的一种手段。本文会对这些并发工具类进行介绍。

    2 等待多线程完成的CountDownLatch

    2.1 CountDownLatch案例演示

    countdownlatch 是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完毕再执行。从命名可以解读到 countdown 是倒数的意思,类似于我们倒计时的概念。
    countdownlatch 提供了两个方法,一个是 countDown,一个是 await,countdownlatch 初始化的时候需要传入一个整数,在这个整数倒数到 0 之前,调用了 await 方法的程序都必须要等待,然后通过 countDown 来倒数。

    public class CountDownLatchDemo {
        public static void main(String[] args) {
            CountDownLatch countDownLatch = new CountDownLatch(6);
            for (int i = 0; i < 6; i++) {
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName()+"同学离开了");
                    countDownLatch.countDown();
                }).start();
            }
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"要关门了,此时教室已经没人了~");
        }
    }

    3 同步屏障CyclicBarrier

    CyclicBarrier的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一 组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会 开门,所有被屏障拦截的线程才会继续运行。

    3.1 CyclicBarrier使用场景

    使用场景:5个工程师一起来公司应聘,招聘方式分为笔试和面试。首先,要等人到齐后,开始笔试;笔试结束之后,再一起参加面试。把5个人看作5个线程,代码如下:
    Main类


    public class Main {
        public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
            CyclicBarrier barrier = new CyclicBarrier(5);
            for (int i = 0; i < 5; i++) {
                new MyThread("线程-" + (i + 1), barrier).start();
            }
        }
    }

    MyThread类:

    public class MyThread extends Thread{
    
        private final CyclicBarrier barrier;
        private final Random random = new Random();
        public MyThread(String name, CyclicBarrier barrier) {
            super(name);
            this.barrier = barrier;
        }
        @Override public void run() {
            try {
                Thread.sleep(random.nextInt(2000));
                System.out.println(Thread.currentThread().getName() + " - 已经到达公司");
                barrier.await();
                Thread.sleep(random.nextInt(2000));
                System.out.println(Thread.currentThread().getName() + " - 已经笔试结束");
                barrier.await();
                Thread.sleep(random.nextInt(2000));
                System.out.println(Thread.currentThread().getName() + " - 已经面试结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            super.run();
        }
    }

    在整个过程中,有2个同步点:第1个同步点,要等所有应聘者都到达公司,再一起开始笔试;第2个同步点,要等所有应聘者都结束笔试,之后一起进入面试环节。

    3.3 CyclicBarrier与CountDownLatch 区别

    CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
    CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法重置,可以使用多次,所以CyclicBarrier能够处理更为复杂的场景;

    4 控制并发线程数的Semaphore

    Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以 保证合理的使用公共资源

    4.1 Semaphore的使用场景

    public class SemaphoreDemo {
        public static void main(String[] args) {
            Semaphore semaphore=new Semaphore(3);//此时海底捞有3个空桌
            for (int i = 0; i < 6; i++) {
                new Thread(() -> {
                    try {
                        semaphore.acquire();
                        System.out.println("第"+Thread.currentThread().getName()+"等待者抢到座位。");
                        //假设每桌客人吃饭时间为3S
                        TimeUnit.SECONDS.sleep(3);
                        System.out.println("第"+Thread.currentThread().getName()+"客人吃完饭离开。");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        semaphore.release();
                    }
                },String.valueOf(i)).start();
            }
        }
    }



    作者:干天慈雨
    链接:https://www.jianshu.com/p/6251c13bbb2e
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    CodeDOM浅析(上)
    这段代码居然运行正常
    CodeDOM浅析(下)
    动态生成与编译(七)根据CodeDOM生成源代码
    动态生成与编译(九)CodeDOM的局限
    动态生成与编译(八)动态编译
    新年送大礼
    祝所有的女性朋友们节日快乐!
    预测人民币在2006年最终的收盘价
    2007年春节,祝朋友们:身体健康,万事如意! 度过一个愉快春节!
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15109025.html
Copyright © 2011-2022 走看看