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

    CountDownLatch实现原理简介:

    CountDownLatch内部维护一个计数器,计数器的值为待完成的任务数N,需要等待这N个任务完成的线程调用CountDownLatch的await()方法使自己进入休眠等待状态。

    当某一个任务线程完成某一个任务后调用CountDownLatch的countDown()方法来表示自己的任务已完成,此时CountDownLatch的计数器值减1,当所有的任务完成式,计数器的值为0。当计数器值为0时,CountDownLatch将唤醒所有因await()方法进入休眠的线程。

    CountDownLatch的使用:

    CountDownLatch的使用主要有3点:

    1、CountDownLatch的声明及初始化,在初始化时需要指定等待完成的任务数。

    2、某一个任务完成时调用CountDownLatch的countDown()方法,向CountDownLatch报告自己的任务已经完成,

    3、需要等待任务完成的线程调用CountDownLatch的await()方法,调用后该线程将进入休眠,并在所有任务数完成后CountDownLatch的计数器值为0时,因await()方法进行休眠的线程将被唤醒。

    在此本人在Java 7并发编程实战手册该书中的CountDownLatch使用示例的基础上做了部分改进,来演示CountDownLatch的使用详情:

    模拟10个参会者和一个主持人参加的一个会以,每个参会者及主持人需要等待其他的参会者均到场签到之后,才能开始会以并发言。为此,先创建一个会以管理的类VideoConference,其提供一个arrive()方法供参会者调用来进行签到。会议管理的拥有者是主持人,其等待每个参会者的签到:

    public class VideoConference implements  Runnable{  
        private final CountDownLatch countDownLatch;  
        private int number;  
        public VideoConference(int number) {  
            this.number = number;  
            this.countDownLatch = new CountDownLatch(number);//使用Number初始化其内部的计数器,当初始化完成后,不能再次初始化  
        }  
        public void arrive(String name){  
            //每个需要同步的任务,在任务完成时,需要调用该方法  
            countDownLatch.countDown();//countDownLatch内部的计数器减1  
            System.out.print("arrive:"+name+"
    ");  
            try{  
                countDownLatch.await();//await方法是线程进入休眠,当countDownLatch计数器为0时,将被唤醒  
                //线程被唤醒,在这里可以执行一系列任务  
                System.out.print("name:"+name + " say:let's start..." +"
    ");  
            }catch (InterruptedException e){  
                e.printStackTrace();  
            }  
        }  
        public void run(){  
            System.out.print("has arrive:"+(number-countDownLatch.getCount())+"
    ");  
            try{  
                countDownLatch.await();//await方法是线程进入休眠,当countDownLatch计数器为0时,将被唤醒  
                //线程被唤醒,在这里可以执行一系列任务  
                System.out.print("all arrived:"+(number-countDownLatch.getCount())+"
    ");  
            }catch (InterruptedException e){  
                e.printStackTrace();  
            }  
        }  
    }  

    创建一个参会者类Participant:

    public class Participant implements  Runnable{  
        private VideoConference videoConference;  
        private String name;  
      
        public Participant(String name, VideoConference videoConference) {  
            this.name = name;  
            this.videoConference = videoConference;  
        }  
        public void run(){  
            try {  
                //do something  
                Thread.sleep(50);  
                //  
                videoConference.arrive(name);  
            }catch (InterruptedException e){  
                e.printStackTrace();  
            }  
        }  
      
        public static void main(String[] args){  
            VideoConference videoConference = new VideoConference(10);  
            Thread videoThread = new Thread(videoConference);  
            videoThread.start();  
            for(int i=0; i<10; i++){  
                Thread thread = new Thread(new Participant("participant:"+i,videoConference));  
                thread.start();  
            }  
        }  
    }  
    

      Participant类中的main函数首先创建了一个需要10个参会者参加的一个会议,之后,创建了10个参会者并逐个签到,在10个参会者都签到之后,每个参会者及主持人将被"唤醒"并发言。

    总结:

    CountDownLatch类解决的是多线程间的同步等待、任务协调问题,应用在如在启动某个程序的主功能前,需要前置完成配置环境检查、网络检查等多个子任务等类似的场景。在Java中,除了使用CountDownLatch来实现多线程间的同步等待以外,还可以使用栅栏技术CyclicBarrier来实现多线程间的同步等待、任务协调。

  • 相关阅读:
    二、网络基础
    Ado.net
    LINQ
    C#[抽象类,接口]
    自定义类库,并引用
    c#重点[封装,继承,多肽]
    c#重点[集合类型]异常,数组,集合ArrayList,List<>,hashTable,hashtable泛型(Dictionary)
    c#重点[数据类型,构造方法,变量,变量,运算符,装箱,拆箱]
    .net reflector激活
    sqlsever备份,还原和导入导出方法
  • 原文地址:https://www.cnblogs.com/bug1024/p/9144097.html
Copyright © 2011-2022 走看看