zoukankan      html  css  js  c++  java
  • CountDownLacth详解

      一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

      用给定的计数 初始化 CounDownLatch。由于调用了countDown() 方法,所以在当前计数到达零之前,await()方法会一直受阻塞。之后,会释放所有等待的线程,await()的所有后续调用都将立即返回。这种现象只出现一次---计数无法被重置。如果需要重置计数,请考虑使用CyclicBarrier。

      CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown()的线程打开入口前,所有调用 await()的线程都一直在入口处等待。用 N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。

      CountDownLatch 的一个有用特性是,它不要求调用 countDown 方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个await()。

      在接下来给出视频会议的例子来说明CountDownLacth的用法,视频会议需要等待多有的参与者都到会后才能开始。视频会议:

    public class VedioConference implements Runnable{
        private CountDownLatch countDownLatch;
        public VedioConference(int count) {
            this.countDownLatch = new CountDownLatch(count);
        }
        public void arrive(String name){
            System.out.println("参与者:"+name+"到达");
            countDownLatch.countDown();
            System.out.println("视频会议还需要等待:"+countDownLatch.getCount()+"名参与者");
        }
        @Override
        public void run() {
            try {
                System.out.println("视频会议共有 :"+countDownLatch.getCount()+"名参与者");
                countDownLatch.await();
                System.out.println("所有参与者都已将到达 ");
                System.out.println("开始会议...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

      参与者:

    public class Participant implements Runnable {
        private VedioConference conference;
        private String name;
        public Participant(VedioConference conference, String name) {
            this.conference = conference;
            this.name = name;
        }
    
        @Override
        public void run() {
            try {
                //线程随机休息一段时间
                Thread.currentThread().sleep((int)(Math.random()*10));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //调用arrive()表示参与者已经到达
            conference.arrive(name);
        }
    }

    测试类:

    public class Main {
        public static void main(String[] args) {
            VedioConference conference=new VedioConference(5);
            Thread conThread=new Thread(conference);
            conThread.start();
            for (int i = 0; i <5; i++) {
                Participant participant=new Participant(conference, "participant"+i);
                Thread thread=new Thread(participant);
                thread.start();
            }
        }
    }

      运行结果:

    视频会议共有 :5名参与者
    参与者:participant2到达
    视频会议还需要等待:4名参与者
    参与者:participant3到达
    视频会议还需要等待:3名参与者
    参与者:participant1到达
    视频会议还需要等待:2名参与者
    参与者:participant4到达
    视频会议还需要等待:1名参与者
    参与者:participant0到达
    视频会议还需要等待:0名参与者
    所有参与者都已将到达 
    开始会议...

      内存一致性效果:线程中调用 countDown() 之前的操作happen-before紧跟在从另一个线程中对应 await() 成功返回的操作。

  • 相关阅读:
    第三节 单因素方差分析
    第四十一节 ORM介绍和用元类实现
    第四十节 通过type创建复杂的类,元类应用
    第二节 检验方法使用条件考察
    HDFS HA误删namenode后报错Nameservice testCluster has no SecondaryNameNode or High-Availability partner的恢复
    spark sql cache时发现的空字符串问题
    centos7环境下ELK部署之elasticsearch
    CDH升级 5.7.5 --> 5.13.3(tar包方式)
    CDH部署(以5.7.5为例)
    人生苦短,Let's Go
  • 原文地址:https://www.cnblogs.com/wxgblogs/p/5424669.html
Copyright © 2011-2022 走看看