• 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

  • 相关阅读:
    第三章:Hadoop简介及配置Hadoop-1.2.1,hbase-0.94.13集群
    maven环境的搭建,lemon-OA办公系统的搭建
    如何打开mo文件并修改 PoEdit
    安装Elastix-2.4版本
    RabbitMQ安装
    Yum编译安装Error Downloading Packages报错
    linux:ping不通www.baidu.com
    tar命令解压缩出错
    PV、UV
    使用存储过程创建数据
  • 原文地址:https://www.cnblogs.com/rocky-fang/p/6763396.html
Copyright © 2020-2023  润新知