浅谈Java中CountDownLatch的用法
来源:互联网 发布:php 敏感词过滤 编辑:程序博客网 时间:2024/04/30 07:08
CountDownLatch位于java.util.concurrent包下,是JDK1.5的并发包下的新特性。
首先根据Oracle的官方文档看看CountDownLatch的定义:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
简单来说,CountDownLatch是一个同步的辅助类,允许一个或多个线程一直等待,直到其它线程完成它们的操作。
这里就涉及两个问题:
1.如何让一个或多个线程一直等待;
2.如何让这些线程知道其它线程已经完成它们的操作
这两个问题主要是使用一个count的属性解决。使用count初始化CountDownLatch,然后需要等待的线程调用await方法。await
方法会一直受阻塞直到count=0。
而其它线程完成自己的操作后,调用countDown()使计数器count减1。当count减到0时,所有在等待的线程均会被释放,并且count无法被重置。如果需要重置,请参考
CyclicBarrier
再来看一个稍微复杂点的例子,10个选手比赛跑步,在枪响后同时起跑,全部到达终点后比赛结束:
1 import java.util.concurrent.CountDownLatch; 2 import java.util.concurrent.ExecutorService; 3 import java.util.concurrent.Executors; 4 5 6 public class CountDownLatchDemo { 7 8 private static int PLAYER_NUM = 10; 9 10 public static void main(String[] args) {11 12 final CountDownLatch beginSignal = new CountDownLatch(1);13 final CountDownLatch endSignal = new CountDownLatch(PLAYER_NUM);14 15 ExecutorService executorService = Executors.newFixedThreadPool(PLAYER_NUM);16 17 for(int i=0;i<PLAYER_NUM;i++){18 final int num = i+1;19 Runnable runner = new Runnable(){20 21 @Override22 public void run() {23 // TODO Auto-generated method stub24 System.out.println("No. "+num+" is waiting...");25 try {26 beginSignal.await();27 System.out.println("No. "+num+" begin running");28 Thread.sleep((long) (Math.random() * 10000));29 System.out.println("No." + num + " arrived");30 } catch (InterruptedException e) {31 // TODO Auto-generated catch block32 e.printStackTrace();33 }finally{34 endSignal.countDown();35 }36 }37 38 };39 executorService.execute(runner);40 }41 42 System.out.println("before Game Start");43 beginSignal.countDown();44 System.out.println("Game Start");45 System.out.println("---In the middle of the game---");46 try {47 endSignal.await();48 } catch (InterruptedException e) {49 // TODO Auto-generated catch block50 e.printStackTrace();51 }finally{52 System.out.println("Game Over!");53 executorService.shutdown();54 }55 56 }57 58 }
以上逻辑不难理解,beginSignal的count=0时,runner线程开始运行,直到endSignal的count=0时结束。
接下来分析一下运行6次的结果:
可以看到,因为有beginSignal,所以可以保证所有runner都waiting以后,才begin running。同理,因为有endSignal,可以保证所有runner arrived后才Game Over!
但是,这里的需要留意主线程的几个输出:
1 System.out.println("before Game Start");2 beginSignal.countDown();3 System.out.println("Game Start");4 System.out.println("---In the middle of the game---");
1.尽管before Game Start在countDown()之前,但不能保证is waiting全部输出完后,才输出before Game Start。
2.“Game Start”和"In the middlel of the game"虽然都在countDown()之后,但在多线程的环境下(主线程也是线程之一),无法预计两个字段输出的位置。从上面的case看,有可能在running的前面,中间和后面,无法预计。这里要十分注意。
3.因为有Thread.sleep,所以arrived都在running之后出现。否则,arrived出现的位置,就不一定都在running之后了。
对于第一点,其实还没想明白,为什么顺序是No.9 is waiting --> before Game Start --> No.10 is waiting 而不是 No.9 is waiting --> No.10 is waiting --> before Game Start?
- 浅谈Java中CountDownLatch的用法
- 浅谈Java中CountDownLatch的用法
- 浅谈CountDownLatch的用法
- Java中CountDownLatch的用法
- Java中CountDownLatch的用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 浅析Java中CountDownLatch用法
- 取消EditText自动聚焦弹出输入框
- UISplitViewController翻译
- 【Linux应用开发】malloc内存分配原理
- 【机器学习实战】制作五子棋AI之一:图片预处理(尺寸变换和增加alpha通道)
- ubuntu服务器安装配置apache2
- 浅谈Java中CountDownLatch的用法
- 【Unity】【UI.Text】【Code】通用代码库(五)——文字循环滚动+touch控制上下滚动
- 非阻塞式socket的select()用法
- mysql操作查询结果case when then else end用法举例
- post提交json数据后,java接收json
- 北大oj-1008 C语言
- 聚簇索引与非聚簇索引的区别
- 数学建模_使用excel对字符串进行截取并简单计数
- 分页