码迷,mamicode.com
首页 > 其他好文 > 详细

【JUC源码解析】CountDownLatch

时间:2018-03-03 16:54:11      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:nbsp   this   shutdown   解析   blog   结果   shu   []   http   

简介

CountDownLatch,是一个同步器,允许一个或多个线程等待,直到一组操作在其他线程中完成。

概述

初始CountDownLatch时,会给定count,await方法会阻塞,直到count减小到0,countDown方法会是count减1,count不能被重置。

应用

例一

描述

有1个老板,雇了10工人,工人就位后,并不是立即工作,而是等到老板发出指令,才会开始工作,每个工人完成工作后,也会发出一个指令反馈完成此工作,而老板会等待所有的工人都完成工作,然后做下一步打算。

代码

 1 public class Driver {
 2     private static final int N = 10;
 3 
 4     public static void main(String[] args) throws InterruptedException {
 5         CountDownLatch startSignal = new CountDownLatch(1);
 6         CountDownLatch doneSignal = new CountDownLatch(N);
 7 
 8         for (int i = 0; i < N; ++i)
 9             new Thread(new Worker("[工人" + i + "]", startSignal, doneSignal)).start(); // 启动工作线程
10 
11         System.out.println("[老板]发出开始信号");
12         startSignal.countDown(); // 发出开始信号
13         doneSignal.await(); // 等待工人们完成
14         System.out.println("[老板]收到所有工人完成的信号");
15     }
16 }
17 
18 class Worker implements Runnable {
19     private final String name;
20     private final CountDownLatch startSignal;
21     private final CountDownLatch doneSignal;
22 
23     Worker(String name, CountDownLatch startSignal, CountDownLatch doneSignal) {
24         this.name = name;
25         this.startSignal = startSignal;
26         this.doneSignal = doneSignal;
27     }
28 
29     public void run() {
30         try {
31             startSignal.await(); // 工人们在此等待老板的开工信号
32             System.out.println(this.name + " >> 开始工作");
33             doWork(); // 开始做工作
34             System.out.println(this.name + " << 完成工作");
35             doneSignal.countDown(); // 发出完成信号
36         } catch (InterruptedException ex) {
37         }
38     }
39 
40     void doWork() {
41         System.out.println(this.name + " == 正在工作");
42     }
43 }

输出

[老板]发出开始信号
[工人0] >> 开始工作
[工人0] == 正在工作
[工人0] << 完成工作
[工人2] >> 开始工作
[工人2] == 正在工作
[工人2] << 完成工作
[工人1] >> 开始工作
[工人1] == 正在工作
[工人1] << 完成工作
[工人4] >> 开始工作
[工人3] >> 开始工作
[工人3] == 正在工作
[工人3] << 完成工作
[工人4] == 正在工作
[工人4] << 完成工作
[工人7] >> 开始工作
[工人6] >> 开始工作
[工人5] >> 开始工作
[工人5] == 正在工作
[工人5] << 完成工作
[工人6] == 正在工作
[工人7] == 正在工作
[工人6] << 完成工作
[工人7] << 完成工作
[工人8] >> 开始工作
[工人8] == 正在工作
[工人8] << 完成工作
[工人9] >> 开始工作
[工人9] == 正在工作
[工人9] << 完成工作
[老板]收到所有工人完成的信号

 

 

例二

描述

有1个很大的任务,可以分成10个子任务,交给10个线程去工作,并在最后汇总结果。

代码

 1 public class Driver2 {
 2     private static final int N = 10;
 3 
 4     public static void main(String[] args) throws InterruptedException {
 5         CountDownLatch startSignal = new CountDownLatch(1);
 6         CountDownLatch doneSignal = new CountDownLatch(N);
 7         ExecutorService e = Executors.newFixedThreadPool(N);
 8 
 9         for (int i = 0; i < N; ++i)
10             e.execute(new WorkerRunnable(startSignal, doneSignal, i));
11 
12         e.shutdown();
13         System.out.println("[总任务]分成" + N + "子任务并开始执行");
14         startSignal.countDown(); // 发出开始信号
15         doneSignal.await();
16         System.out.println("[总任务]已经完成");
17     }
18 }
19 
20 class WorkerRunnable implements Runnable {
21     private final CountDownLatch startSignal;
22     private final CountDownLatch doneSignal;
23     private final int i;
24 
25     WorkerRunnable(CountDownLatch startSignal, CountDownLatch doneSignal, int i) {
26         this.startSignal = startSignal;
27         this.doneSignal = doneSignal;
28         this.i = i;
29     }
30 
31     public void run() {
32         try {
33             startSignal.await();
34         } catch (InterruptedException e) {
35         }
36         System.out.println("[子任务" + i + "]>>开始执行");
37         doWork(i);
38         doneSignal.countDown();
39         System.out.println("[子任务" + i + "]==已经完成");
40     }
41 
42     void doWork(int i) {
43         System.out.println("[子任务" + i + "]==正在执行");
44     }
45 }

 

输出

[总任务]分成10子任务并开始执行
[子任务1]>>开始执行
[子任务1]==正在执行
[子任务1]==已经完成
[子任务4]>>开始执行
[子任务4]==正在执行
[子任务4]==已经完成
[子任务3]>>开始执行
[子任务3]==正在执行
[子任务3]==已经完成
[子任务0]>>开始执行
[子任务0]==正在执行
[子任务0]==已经完成
[子任务6]>>开始执行
[子任务6]==正在执行
[子任务6]==已经完成
[子任务2]>>开始执行
[子任务2]==正在执行
[子任务2]==已经完成
[子任务5]>>开始执行
[子任务5]==正在执行
[子任务5]==已经完成
[子任务7]>>开始执行
[子任务8]>>开始执行
[子任务9]>>开始执行
[子任务7]==正在执行
[子任务9]==正在执行
[子任务8]==正在执行
[子任务9]==已经完成
[子任务7]==已经完成
[子任务8]==已经完成
[总任务]已经完成

 

源码分析

 


尊重他人的劳动,转载请注明出处:http://www.cnblogs.com/aniao/p/aniao_cdl.html

【JUC源码解析】CountDownLatch

标签:nbsp   this   shutdown   解析   blog   结果   shu   []   http   

原文地址:https://www.cnblogs.com/aniao/p/aniao_cdl.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!