zoukankan      html  css  js  c++  java
  • java.util.concurrent.CountDownLatch 使用

    1. 概述

       CountDownLatch是java的一个并发工具(java.util.concurrent.CountDownLatch), 闭锁。

       主要功能是阻塞调用其await()方法的线程,直到其他线程调用countDown()使得count(计数器)变为0时立即从await返回

    2. 主要应用场景

       2.1 主线程等待各子线程完成子任务再开始执行

      

    package countDownLatch;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.CountDownLatch;
    
    public class CountDownLatchTestAllDoneNotifyMain {
    
        
        static CountDownLatch latch = new CountDownLatch(3);
        public static void main(String[] args) throws InterruptedException{
            System.out.println("Time point one:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            new Thread(){
                public void run(){
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("sub task 1 done");
                    latch.countDown();
                }
            }.start();
            new Thread(){
                public void run(){
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("sub task 2 done");
                    latch.countDown();
                }
            }.start();
            new Thread(){
                public void run(){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("sub task 3 done");
                    latch.countDown();//
                }
            }.start();
            
            latch.await();//阻塞 直到构造的3变为0
            System.out.println("Time point two:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            System.out.println("sub task all done, and main task running.....");
        }
    }

    2.2 多个线程等待(await),被一个线程同时唤醒(countDown), 初始count为1

    package countDownLatch;
    
    import java.util.concurrent.CountDownLatch;
    
    public class CountDownLatchTestOneDoneNotifyAll {
    
        private static CountDownLatch latch = new CountDownLatch(1);
        public static void main(String[] args) throws InterruptedException {
            for(int i=0; i<3; i++){
                new Thread(){
                    public void run(){
                        System.out.println(Thread.currentThread().getName()+" waiting...");
                        try {
                            latch.await();
                            System.out.println(Thread.currentThread().getName()+" running");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }.start();
            }
            System.out.println("Main thread do something...");
            Thread.sleep(2000);
            System.out.println("Sub Thread begin to run...");
            latch.countDown();
        }
    }

     两种场景一起测试

    package countDownLatch;
    
    import java.util.concurrent.CountDownLatch;
    
    public class Driver {
    
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch startSignal = new CountDownLatch(1);
            CountDownLatch doneSignal = new CountDownLatch(3);
            for(int i=0; i<3; i++) {
                new Thread(new Worker(startSignal, doneSignal)).start();
            }
            doSomething();
            startSignal.countDown();
            doSomething();
            doneSignal.await();
        }
    
        private static void doSomething() {
            // TODO Auto-generated method stub
            
        }
        
    }
    
    class Worker implements Runnable{
        private CountDownLatch startSignal;
        private CountDownLatch doneSignal;
        Worker(CountDownLatch startSignal, CountDownLatch doneSignal){
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
        }
        public void run(){
            try {
                startSignal.await();
                doWork();
                doneSignal.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        private void doWork() {
            
        }
    }

     3. note

        3.1 countDown()可以被一个线程执行多次,count随之减1;

        3.2 在直接创建子线程使用时可以使用Thread.join()达到主线程等待子线程忙完在执行的效果,

              在使用线程池等情境下, 没法直接操作线程, 可以使用CountDownLatch

  • 相关阅读:
    移动APP的开发需求分析
    我心中的理想团队和对软件开发流程的理解
    Git 命令
    在Visio2010中修改默认字体的大小
    Remove @Override annotation错误提示
    SPRING框架中ModelAndView、Model、ModelMap区别
    select count(*)和select count(1)的区别
    eclipse 关键字高亮显示
    MyEclipse下安装MyBatis Generator代码反向生成工具
    关于 log4j.additivity的说明
  • 原文地址:https://www.cnblogs.com/rocky-fang/p/6763396.html
Copyright © 2011-2022 走看看