java并发编程中CountDownLatch和CyclicBarrier的使用
在多线程程序设计中,经常会遇到一个线程等待一个或多个线程的场景,遇到这样的场景应该如何解决?
如果是一个线程等待一个线程,则可以通过await()和notify()来实现;
如果是一个线程等待多个线程,则就可以使用CountDownLatch和CyclicBarrier来实现比较好的控制。
下面来详细描述下CountDownLatch的应用场景:
例如:百米赛跑:8名运动员同时起跑,由于速度的快慢,肯定有会出现先到终点和晚到终点的情况,而终点有个统计成绩的仪器,当所有选手到达终点时,它会统计所有人的成绩并进行排序,然后把结果发送到汇报成绩的系统。
其实这就是一个CountDownLatch的应用场景:一个线程或多个线程等待其他线程运行达到某一目标后进行自己的下一步工作,而被等待的“其他线程”达到这个目标后继续自己下面的任务。
这个场景中:
1. 被等待的“其他线程”------>8名运动员
2. 等待“其他线程”的这个线程------>终点统计成绩的仪器
那么,如何来通过CountDownLatch来实现上述场景的线程控制和调度呢?
jdk中CountDownLatch类有一个常用的构造方法:CountDownLatch(int count);
两个常用的方法:await()和countdown()
其 中count是一个计数器中的初始化数字,比如初始化的数字是2,当一个线程里调用了countdown(),则这个计数器就减一,当线程调用了 await(),则这个线程就等待这个计数器变为0,当这个计数器变为0时,这个线程继续自己下面的工作。下面是上述CountDownLatch场景的 实现:
Work类(运动员):
import Java.util.concurrent.CountDownLatch;
public class Work implements Runnable {
private int id;
private CountDownLatch beginSignal;
private CountDownLatch endSignal;
public Work(int id, CountDownLatch begin, CountDownLatch end) {
this.id = id;
this.beginSignal = begin;
this.endSignal = end;
}
@Override
public void run() {
try {
beginSignal.await();
System.out.println("起跑...");
System.out.println("work" + id + "到达终点");
endSignal.countDown();
System.out.println("work" + id + "继续干其他事情");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Main类(终点统计仪器):
import java.util.concurrent.CountDownLatch;
public class Main {
public static void main(String[] args) {
CountDownLatch begSignal = new CountDownLatch(1);
CountDownLatch endSignal = new CountDownLatch(8);
for (int i = 0; i < 8; i++) {
new Thread(new Work(i, begSignal, endSignal)).start();
}
try {
begSignal.countDown(); //统一起跑
endSignal.await(); //等待运动员到达终点
System.out.println("结果发送到汇报成绩的系统");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
下面详细描述下CyclicBarrier的应用场景:
有四个游戏玩家玩游戏,游戏有三个关卡,每个关卡必须要所有玩家都到达后才能允许通关。
其 实这个场景里的玩家中如果有玩家A先到了关卡1,他必须等待其他所有玩家都到达关卡1时才能通过,也就是说线程之间需要互相等待,这和 CountDownLatch的应用场景有区别,CountDownLatch里的线程是到了运行的目标后继续干自己的其他事情,而这里的线程需要等待其 他线程后才能继续完成下面的工作。
jdk中CyclicBarrier类有两个常用的构造方法:
1. CyclicBarrier(int parties)
这里的parties也是一个计数器,例如,初始化时parties里的计数是3,于是拥有该CyclicBarrier对象的线程当parties的计数为3时就唤醒,注:这里parties里的计数在运行时当调用CyclicBarrier:await()时,计数就加1,一直加到初始的值
2. CyclicBarrier(int parties, Runnable barrierAction)
这里的parties与上一个构造方法的解释是一样的,这里需要解释的是第二个入参(Runnable barrierAction),这个参数是一个实现Runnable接口的类的对象,也就是说当parties加到初始值时就出发barrierAction的内容。
下面来实现上述的应用场景:
Player类(玩家类)
- import java.util.concurrent.BrokenBarrierException;
- import java.util.concurrent.CyclicBarrier;
- public class Player implements Runnable {
- private CyclicBarrier cyclicBarrier;
- private int id;
- public Player(int id, CyclicBarrier cyclicBarrier) {
- this.cyclicBarrier = cyclicBarrier;
- this.id = id;
- }
- @Override
- public void run() {
- try {
- System.out.println("玩家" + id + "正在玩第一关...");
- cyclicBarrier.await();
- System.out.println("玩家" + id + "进入第二关...");
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (BrokenBarrierException e) {
- e.printStackTrace();
- }
- }
- }
GameBarrier类(关卡类,这里控制玩家必须全部到达第一关结束的关口才能进入第二关)
import java.util.concurrent.CyclicBarrier;
public class GameBarrier {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(4, new Runnable() {
@Override
public void run() {
System.out.println("所有玩家进入第二关!");
}
});
for (int i = 0; i < 4; i++) {
new Thread(new Player(i, cyclicBarrier)).start();
}
}
}
java并发编程中CountDownLatch和CyclicBarrier的使用的更多相关文章
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- 14、Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- 【转】Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在j ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore (总结)
下面对上面说的三个辅助类进行一个总结: 1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: CountDownLatch一般用于某个线程A等待 ...
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
原文出处: 海子 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅 ...
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore[转]
[转载]http://www.cnblogs.com/dolphin0520/p/3920397.html 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDow ...
- Java并发编程: CountDownLatch、CyclicBarrier和 Semaphore
java 1.5提供了一些非常有用的辅助类来帮助并发编程,比如CountDownLatch,CyclicBarrier和Semaphore. 1.CountDownLatch –主线程阻塞等待,最后完 ...
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore , Condition
http://www.importnew.com/21889.html 1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: CountDown ...
- Java并发编程中的相关注解
引自:http://www.cnblogs.com/phoebus0501/archive/2011/02/21/1960077.html Java并发编程中,用到了一些专门为并发编程准备的 Anno ...
随机推荐
- 初识IT行业,人生苦短,我学python
第一次写,我也不知道该怎么写.只有慢慢的去体会大神们的见解与看法. Python是一个较强的脚本语言,而Java是强类型的编程语言.为了更好的入门,我没有去选择强类型语言的Java,而选择使用Pyth ...
- jmeter线程组介绍
Jmeter中的测试计划是一直有的,但可以在右侧修改名字,要开始做具体测试设计前,都需要在测试计划下边添加一个线程组,添加路径为鼠标捕获测试计划后,点击鼠标右键->添加->Threads( ...
- .Net 如何访问主流的各大数据库
做过开发的都知道,.NET基本可以理解是和MSSQL,windows服务器属于一个好的搭档,正如PHP和MYSQL,LIUNX等也可以理解是一个完美搭配:但是在实际的开发中并不完全是这样的,如果你是学 ...
- Python中的常规习题
循环总结 while 语句 for 语句 - 字符串 - range() 函数 break 语句 continue 语句 学习笔记传送门 列表学习 # 练习: # 输入一个整数n, 判断这个整数是否是 ...
- hadoop最新稳定版本使用建议
Apache Hadoop Apache版本衍化比较快,我给大家介绍一下过程 ApacheHadoop版本分为两代,我们将第一代Hadoop称为Hadoop 1.0,第二代Hadoop称为Hadoop ...
- resize2fs命令详解
基础命令学习目录首页 原文链接:http://blog.51cto.com/woyaoxuelinux/1870299 resize2fs:调整ext文件系统的空间大小 搭配逻辑卷lv使用方法: ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)的解决
在用爬虫爬取网络小说的时候出现该问题. 估计是字符格式转换格式的错误. 暂时无法解决,搜索了其他博主的解决方案. 以下两个方案靠谱: <一>适用于全篇 import sys default ...
- Task 6.4 冲刺Two之站立会议6
今天对视频的画面质量进行了优化,又把所有的界面更换了一些比较美观的图片和背景.使界面看起来更加地合理,易于接受.
- srTCM和trTCM介绍
本文是用于QoS Meter功能的算法的RFC的阅读笔记.DPDK的QoS_meter示例程序用的就是这个算法. srTCM srTCM的英文全称是Single Rate Three Color Ma ...
- 404 Note Found 团队会议纪要
目录 团队会议 会议纪要1 会议纪要2 会议纪要3 会议纪要4 会议纪要5 会议纪要6 团队会议 会议纪要1 会议纪要2 会议纪要3 会议纪要4 会议纪要5 会议纪要6