zoukankan      html  css  js  c++  java
  • CountDownLatch 使用

        CountDownLatch 是一种同步辅助工具, 它允许一个或多个线程等待 直到其它线程的一组操作完成。JDK 1.5加入 。

       给定count可以获取CountDownLatch对象。类似于一种记数器,通过getCount()可获知还有多少线程没有执行完成。调用await()方法表示进入阻塞,直到count变成0, 程序方可执行下去。

     

      主线程Tm,调用具体执行业务内容的异步线程组(T0,T1,T2,T3),接下来调用await()方法,让主线程进行等待中。 当前count=4。 异步线程组中的每个线程执行完成后,都 会调用countDown(),表示对count进行减1操作。当四个线程全部执行完成,count==0,则主线程Tm继续往下执行。

      构造函数:CountDownLatch latch = new CountDownLatch(count)

      需要注意的是,初始化CountDownLatch时的count必需与异步线程组的线程数保持一致,线程数多或少于count,会出现永远等待或业务没有执行完成主线程就往下执行了。

      主要的应用场景: 一个业务分多步骤,每个步骤中又分多个并行子模块,子模块全部完成才能进行到下一步。 比如,一张综合性报表是由几张小报表汇总而成,必需要先执行完所有的小报表,方可执行综合性报表汇总。

      核心方法:

      countDown(): 减少计数, 如果计数为0,则释放所有的等待线程。  如果计数大于0,则进行计数减1; 如果计数=0,则什么都不会发生。

      await():线程阻塞。1、计数count=0,2、线程发生interrupt异常。 如果计数=0,则方法立即返回。

      await(long timeout, TimeUnit unit):线程阻塞。1、计数count=0;2、线程发生interrupt异常;3、等待超时。

      代码实现:

    第一种:

    public void run1(){
            LocalDateTime beginTime = LocalDateTime.now();
            Thread[] threads = new Thread[10];
            CountDownLatch latch = new CountDownLatch(threads.length);
    
            for (int i=0;i<threads.length;i++){
                threads[i] = new Thread(()->{
    
                    /**
                     * 执行业务流程
                     */
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    latch.countDown();
                    System.out.println(LocalDateTime.now()+"==="+Thread.currentThread().getName());
                },"t"+i);
            }
    
            for (Thread t : threads){
                t.start();
            }
    
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(beginTime+"---------end latch>>>>"+LocalDateTime.now());
        }
    

    第二种:使用线程池

    public void run2()  {
            LocalDateTime beginTime = LocalDateTime.now();
            int threadCount = 10 ;
            CountDownLatch doneLatch = new CountDownLatch(threadCount);
            Executor executor = Executors.newFixedThreadPool(threadCount);
    
            for (int i = 0; i < threadCount; i++) {
                executor.execute(new WorkRunnable(doneLatch, i));
            }
    
            try {
                doneLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(beginTime+"---------end latch>>>>"+LocalDateTime.now());
        }
    
    
    class WorkRunnable implements  Runnable {
    
        private CountDownLatch latch ;
        private int index;
    
        public WorkRunnable(CountDownLatch latch, int index){
            this.latch = latch;
            this.index = index;
        }
    
        @Override
        public void run() {
    
            /**
             * 执行业务流程
             */
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            System.out.println(LocalDateTime.now()+"  =>  "+index);
        }
    }
    
  • 相关阅读:
    读取.robot文件写入excel文件中示例
    提示框、滚动条处理与JS的应用
    下拉框
    切换框架ifame
    层级定位
    定位一组元素
    Appium元素定位方法
    python+appium基本启动配置
    adb命令使用
    Python接口测试框架搭建
  • 原文地址:https://www.cnblogs.com/song27/p/13062135.html
Copyright © 2011-2022 走看看