• 多线程之CountDownLatch和CyclicBarriar使用


      CountDownLatch和CyclicBarriar是java.util.concurrent包下面提供的多线程同步工具,两者有点相似,相当于计数器,但是用处还是有区别的。

      CountDownLatch:用于在完成一组正在其它线程中执行的操作之前,它允许一个或多个线程一直等待,await()表示等待,等到其它线程全部执行结束后(即通过countDown()方法来减数,计数为0,即其它线程执行完毕)然后继续执行,示例代码:

    public static void main(String[] args) {
            //该计数器初始值1,用于主线程发送命令
            final CountDownLatch latch1 = new CountDownLatch(1);
            //该计数器初始值为2,用于响应命令接受完成
            final CountDownLatch latch2 = new CountDownLatch(2);
            //创建一个大小为2线程池
            ExecutorService executor = Executors.newCachedThreadPool(); 
            for (int i = 0; i < 2; i++) {
                executor.submit(new Runnable() {
                    public void run() {
                        try {
                            System.out.println("线程" + Thread.currentThread().getName() + "正准备接受命令");
                            //等待主线程发送命令
                            latch1.await();
                            System.out.println("线程" + Thread.currentThread().getName() + "已接受命令");
                            Thread.sleep((long) (Math.random() * 10000));
                            System.out.println("线程" + Thread.currentThread().getName() + "回应命令处理结果");
                            //命令接受完毕,返回给主线程,latch2减1。
                            latch2.countDown();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            try {
                Thread.sleep((long) (Math.random() * 10000));
                System.out.println("线程" + Thread.currentThread().getName() + "即将发布命令");
                //发送命令,latch1计数减1
                latch1.countDown(); 
                System.out.println("线程" + Thread.currentThread().getName() + "已发送命令,正在等待响应");
                //命令发送后处于等待状态,其它线程全部响应完成,也就是latch2.countDown(),再继续执行
                latch2.await(); 
                System.out.println("线程" + Thread.currentThread().getName() + "已收到所有响应结果");
            } catch (Exception e) {
                e.printStackTrace();
            }
            //关闭线程池
            executor.shutdown(); 
        }

      CyclicBarriar:用于多个线程在一个指定的公共屏障点(或者说集合点)相互等待,await()方法代表屏障点,每次调用await(),计数(创建CyclicBarriar对象时传入int类型的参数,表示初始计数)减一,直到减到0后,表示所有线程都抵达,然后开始执行后面的任务,示例代码:

    public static void main(String[] args) throws Exception {
            //创建CyclicBarrier对象并设置2个公共屏障点
            final CyclicBarrier barrier = new CyclicBarrier(2);
            //创建大小为2的线程池
            ExecutorService executor = Executors.newFixedThreadPool(2);
            for (int i = 0; i < 2; i++) {
                executor.submit(new Runnable() {
                    public void run() {
                        try {
                            Thread.sleep((long)(Math.random()*10000));
                            System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有"
                                    + barrier.getNumberWaiting() + "个已经到达,正在等候");
                            //如果没有达到公共屏障点,则该线程处于阻塞状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行
                            barrier.await();
                            
                            System.out.println("线程" + Thread.currentThread().getName() + "通过集合地点1");
                            
                            Thread.sleep((long)(Math.random()*10000));
                            System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有"
                                    + barrier.getNumberWaiting() + "个已经到达,正在等候");
                            barrier.await();
                            
                            System.out.println("线程" + Thread.currentThread().getName() + "通过集合地点2");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            //关闭线程池
            executor.shutdown();
        }

      注意:观察CyclicBarrier的使用可以发现,它计数减至0后,计数器会被重置,可以再次使用,可能这也是它被定义为Cyclic(周期的、循环的)原因,这个是和CountDownLatch区别的地方。

  • 相关阅读:
    【BZOJ 4151 The Cave】
    【POJ 3080 Blue Jeans】
    【ZBH选讲·树变环】
    【ZBH选讲·拍照】
    【ZBH选讲·模数和】
    【CF Edu 28 C. Four Segments】
    【CF Edu 28 A. Curriculum Vitae】
    【CF Edu 28 B. Math Show】
    【CF Round 439 E. The Untended Antiquity】
    【CF Round 439 C. The Intriguing Obsession】
  • 原文地址:https://www.cnblogs.com/handsomeye/p/6421394.html
Copyright © 2020-2023  润新知