CountDownLatch认知——同步协调器

原创 2016年08月29日 09:55:48

简介

java.util.concurrent.CountDownLatchJDK1.5引入的并法包中的一个工具类,用来做并发线程间的同步。

我们来看一下它的类说明信息:

一个同步辅助,它允许一个或者多个线程等待——直到一系列在其他线程中的操作完成之后才进行。

一个CountDownLatch 由一个给定的count总数初始化。await方法会一直阻塞直到当前count值被countDown方法的调用减为零,之后,所有等待线程被释放,任何后续await方法的调用立即返回。这种现象是一次性的——count值不能被重置。如果你想要count能被重置,请考虑使用CyclicBarrier

一个CountDownLatch是一个万能的同步工具,它可以被用在很多场景中。CountDownLatch类似于简单开关门闩,或者说大门:所有调用await的线程在大门外等待直到大门被一个调用countDown的线程打开。一个CountDownLatch的计数器被初始化为N,可以使一个线程等待直到N个线程完成了某些操作,或者某些操作被完成了N次。

CountDownLatch 一个有用的特性是它并不要求调用countDown的线程必须等待count值减为零之后才能进行,它只是简单地阻止任意的线程执行传递await信号直到所有线程可以传递这个信号。


协调器

所以,我所理解的这个类的最主要的作用就是:用来做线程同步的协调器
讲一个我理解的场景:

大学里的体育课,这里边有两个角色:体育老师和学生。上课开始的前15分钟,体育老师定为热身阶段,让大家先去跑个1000米,跑完的同学先去自由休息,听老师命令,到指定地点正式上课。

这个场景就非常适合用CountDownLath来做协调。
伪代码标识为:

//体育老师宣布活动
//以学生总数目作为CountDownLath的计数器的初始值
//每个学生都是一个线程,并持有CountDownLath的引用
//所有学生在起跑线预备,等待体育老师鸣哨
//体育老师鸣哨,计时开始,然后就去凉快的地方待着
//学生在听到哨声之后,开始各自奔跑
//每个学生在跑过终点之后,CountDownLath的计数器减一
//所有跑完,CountDownLath为零,老师回到操场,宣布下一个活动

示例

官方给的使用样例:这里有一对儿类,它们有一组工作线程使用两个countdown latch。

一开始的start(开始)信号,阻止任意的worker执行直到driver已经准备好执行;
第二个的completion(完成)信号,允许dirver等待直到所有worker已经完成。

 class Driver { // ...
   void main() throws InterruptedException {
     CountDownLatch startSignal = new CountDownLatch(1);
     CountDownLatch doneSignal = new CountDownLatch(N);

     for (int i = 0; i < N; ++i) // create and start threads
       new Thread(new Worker(startSignal, doneSignal)).start();

     doSomethingElse();            // don't let run yet
     startSignal.countDown();      // let all threads proceed
     doSomethingElse();
     doneSignal.await();           // wait for all to finish
   }
 }
 class Worker implements Runnable {
   private final CountDownLatch startSignal;
   private final CountDownLatch doneSignal;
   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
     this.startSignal = startSignal;
     this.doneSignal = doneSignal;
   }
   public void run() {
     try {
       startSignal.await();
       doWork();
       doneSignal.countDown();
     } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }}

另外一个典型的应用是把一个问题分解为N个部分,每个部分用一个Runnable来描述,一个Runnable执行每个部分并削减latch,然后将所有的Runnable送到一个Executor的队列中。当所有的子部分都完成了,协调线程会传递一个await信号(当线程必须以这种方式重复削减的时候,请使用CyclicBarrier)。

 class Driver2 { // ...
   void main() throws InterruptedException {
     CountDownLatch doneSignal = new CountDownLatch(N);
     Executor e = ...

     for (int i = 0; i < N; ++i) // create and start threads
       e.execute(new WorkerRunnable(doneSignal, i));

     doneSignal.await();           // wait for all to finish
   }
 }
 class WorkerRunnable implements Runnable {
   private final CountDownLatch doneSignal;
   private final int i;
   WorkerRunnable(CountDownLatch doneSignal, int i) {
     this.doneSignal = doneSignal;
     this.i = i;
   }
   public void run() {
     try {
       doWork(i);
       doneSignal.countDown();
     } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

内存一致性影响:直到计数器减为零,线程中countDown方法被调用之前的动作happen-before于后续的另外一个线程中相应的await()方法成功返回之后的动作。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java并发编程-同步辅助类之CountDownLatch

CountDownLatch是Java Concurrent包下提供的同步辅助类。在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。和Semaphore类似,它使用一个整数进行初始化,Sem...
  • chenchaofuck1
  • chenchaofuck1
  • 2016年06月06日 17:03
  • 1286

zigbee 4:协调器/路由器/终端 建立/加入 网络

2015-02-15 星期日 3:35:47 1、协调器建立网络流程 Init 1 2 3 4 5 6 7 8 ...
  • angelzyb
  • angelzyb
  • 2015年02月27日 20:27
  • 2037

ZigBee中协调器如何向子节点发消息?

介绍了ZigBee协调器向子节点发送消息的方法。
  • ganzi1991
  • ganzi1991
  • 2015年06月02日 20:40
  • 3457

CC2530作为协调器或路由器,最大可以带多少子节点

默认值是5、20、6,共3万个节点。  MAX_DEPTH决定了网络的最大深度。协调器(Coordinator)位于深度0,MAX_DEPTH 参数限制了网络在物理上的长度,这个值默认是5,最大不...
  • xingqingly
  • xingqingly
  • 2015年08月21日 18:04
  • 2291

zigbee网络启动流程 ---- 协调器

 main()->osal_init_system()->osalInitTasks()->ZDApp_Init() 进入ZDApp_Init()函数: void ZDApp_Init(...
  • u013243314
  • u013243314
  • 2014年06月27日 16:55
  • 1025

zigbee终端向多个协调器发起请求的思路(终端入网流程分析)

一个ZigBee终端周围可能有多个协调器,如何让终端连接到指定的协调器? 先简单的谈一下终端的入网流程(相关代码自己去看源码): 1,终端上电,调用ZDOInitDevice初始化ZDO层的tas...
  • PZ0605
  • PZ0605
  • 2017年03月16日 11:06
  • 1046

Zigbee网络设备启动流程—协调器(自启动模式)

使用的协议栈版本信息: ZigBee2006\ZStack-1.4.3-1.2.1 Zigbee网络设备启动流程—协调器(自启动模式)—以SampleApp的协调器为例.   1、协调器预编译信...
  • xiaoaide01
  • xiaoaide01
  • 2014年05月10日 15:45
  • 1093

Java中使用CountDownLatch进行多线程同步

CountDownLatch介绍在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法:1、synchronized关键字进行同步。2、Lock锁接口及其实现类ReentrantLock...
  • zbc1090549839
  • zbc1090549839
  • 2016年12月05日 14:37
  • 921

协调器断电之后再上电,终端设备不能入网

最近遇到个问题,在ZigBee网络中,当终端设备断电之后,发现不能再次加入网络。 看到飞比论坛上有朋友遇到过协调器断电之后再上电,终端设备不能入网的问题。其原因如下: 网络组好后,将协调器关掉,路...
  • shiwaxinbin
  • shiwaxinbin
  • 2013年08月09日 16:21
  • 2966

Android 价值千万java多线程同步 <五>CountDownLatch(计数器)和Semaphore(信号量)

Semaphore Semaphore是一个计数信号量,它的本质是一个"共享锁",以控制某个资源可被同时访问的个数,提供同步机制 信号量维护了一个信号量许可集。线程可以通过调用acquire...
  • WHB20081815
  • WHB20081815
  • 2017年03月30日 20:49
  • 433
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CountDownLatch认知——同步协调器
举报原因:
原因补充:

(最多只允许输入30个字)