zoukankan      html  css  js  c++  java
  • Java并发工具类-CountDownLatch

    一、简述

      CountDownLatch是一个用来控制并发的很常见的工具,它是java.util.concurrent包中一个类,CountDownLatch主要提供的机制是当多个(具体数量等于初始化CountDownLatch时count参数的值)线程都达到了预期状态或完成预期工作时触发事件,其他线程可以等待这个事件来触发自己的后续工作。到达自己预期状态的线程会调用CountDownLatch的countDown方法,而等待的线程会调用CountDownLatch的await方法。

      CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果想要等待N个点完成,这里就传入N。

      如果某个工作线程处理的比较慢,我们不能让主线程一直等待下去。所以可以使用另外一个带指定时间的await方法----await(long time,TimeTnit unit),这个方法等待制定时间后,就不会阻塞当前线程。

      注意:计数器必须大于等于0,当计数器等于0时,调用await方法不会阻塞当前线程;

    二、CountDownLatch使用示例

    import java.util.concurrent.CountDownLatch;
    
    public class CountDownLatchDemo {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch latch = new CountDownLatch(2);//两个线程工作
            new Worker("work1", 200, latch).start();
            new Worker("work2", 300, latch).start();
            latch.await();//等待所有线程完成
            System.out.println("工作全部完成");
        }
    
        static class Worker extends Thread {
            String workName;
            int workTime;
            CountDownLatch latch;
    
            public Worker(String workName, int workTime, CountDownLatch latch) {
                this.workName = workName;
                this.workTime = workTime;
                this.latch = latch;
            }
    
            public void run() {
                System.out.println(workName + "开始工作");
                doWork();
                System.out.println(workName + "结束工作");
                latch.countDown();//完成工作,计数器减一  
            }
    
            private void doWork() {
                try {
                    Thread.sleep(workTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    三、与join的比较

      相比于同样可以让一个线程等待子线程完成的join,CountDownLatch通过计数器提供了更灵活的控制,调用countDown方法是,N就会减1,CountDownLatch的await方法会阻塞当前线程,知道N变为0,由于countDown方法可以用在任何地方,所以这里说的N个点可以是N个线程,也可以是N个执行步骤。

      而join是用于让当前线程等待JOIN线程执行结束。其实现原理是不停检查JOIN线程是否存活,如果JOIN线程存活则让当前线程永远等待。

    示例如下:

    import java.util.concurrent.CountDownLatch;
    
    public class CountDownLatchDemo {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch latch = new CountDownLatch(2);//两个线程工作
            new Worker("work1", 200, latch).start();
            new Worker("work2", 300, latch).start();
            latch.await();//等待所有线程完成
            System.out.println("工作全部完成");
        }
    
        static class Worker extends Thread {
            String workName;
            int workTime;
            CountDownLatch latch;
    
            public Worker(String workName, int workTime, CountDownLatch latch) {
                this.workName = workName;
                this.workTime = workTime;
                this.latch = latch;
            }
    
            public void run() {
                System.out.println(workName + "开始工作");
                doWork();
                System.out.println(workName + "结束工作");
                latch.countDown();//完成工作,计数器减一  
                System.out.println(workName + "开始第二阶段工作");
                doWork();
                System.out.println(workName + "结束第二阶段工作");
            }
    
            private void doWork() {
                try {
                    Thread.sleep(workTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    打印结果如下:

    work1开始工作
    work2开始工作
    work1结束工作
    work1开始第二阶段工作
    work2结束工作
    工作全部完成
    work2开始第二阶段工作
    work1结束第二阶段工作
    work2结束第二阶段工作
  • 相关阅读:
    求解答可用性测试记
    Teambition可用性测试记
    海丁网可用性测试记
    go语言的切片
    go语言的数组
    go语言的函数
    go语言的接口
    go语言的结构体
    go语言的flag
    创建二叉树和三种遍历
  • 原文地址:https://www.cnblogs.com/ljch/p/12129176.html
Copyright © 2011-2022 走看看