java中的线程(4):常用同步类 CountDownLatch、CyclicBarrier和Semaphore
转自:
http://www.cnblogs.com/dolphin0520/p/3920397.html
1.简介
- CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同。
- CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行
- CyclicBarrier 回环栅栏,一般用于一组线程互相等待至某个状态,然后这一组线程再同时开始执行后续任务
- CountDownLatch 在使用完后不可重用
- CyclicBarrier 使用完后可重用
- Semaphore 信号量,一般用于控制对某组资源的访问权限。
2.CountDownLatch示例
void testCountDownLatch() {
final CountDownLatch latch = );
new Thread() {
public void run() {
try {
Log.d(TAG, "子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep();
Log.d(TAG, "子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
;
}.start();
new Thread() {
public void run() {
try {
Log.d(TAG, "子线程" + Thread.currentThread().getName() + "正在执行");
Thread.sleep();
Log.d(TAG, "子线程" + Thread.currentThread().getName() + "执行完毕");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
;
}.start();
try {
Log.d(TAG, "等待2个子线程执行完毕...");
latch.await();
Log.d(TAG, "2个子线程已经执行完毕");
Log.d(TAG, "继续执行主线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
3.CyclicBarrier示例
static class Writer extends Thread {
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
Log.d(TAG, "线程" + Thread.currentThread().getName() + "正在写入数据...");
try {
Thread.sleep(); //以睡眠来模拟写入数据操作
Log.d(TAG, "线程" + Thread.currentThread().getName() + "写入数据完毕,等待其他线程写入完毕");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
Log.d(TAG, "所有线程写入完毕,继续处理其他任务...");
}
}
//用来阻塞当前线程,直至所有线程都到达barrier状态再同时执行后续任务;
void testCyclicBarrier1(){
;
CyclicBarrier barrier = new CyclicBarrier(N);
; i < N; i++) {
new Writer(barrier).start();
}
}
//如果说想在所有线程写入操作完之后,进行额外的其他操作可以为CyclicBarrier提供Runnable参数
void testCyclicBarrier2(){
;
CyclicBarrier barrier = new CyclicBarrier(N, new Runnable() {
@Override
public void run() {
Log.d(TAG, "当前线程" + Thread.currentThread().getName());
}
});
; i < N; i++){
new Writer(barrier).start();
}
}
//CyclicBarrier是可以重用的
void testCyclicBarrier3(){
;
CyclicBarrier barrier = new CyclicBarrier(N);
; i < N; i++) {
new Writer(barrier).start();
}
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "CyclicBarrier重用");
; i < N; i++) {
new Writer(barrier).start();
}
}
//故意让最后一个线程启动延迟,因为在前面三个线程都达到barrier之后,
//等待了指定的时间发现第四个线程还没有达到barrier,就抛出异常并继续执行后面的任务。
void testCyclicBarrier4(){
;
CyclicBarrier barrier = new CyclicBarrier(N);
; i < N; i++) {
)
new Writer2(barrier).start();
else {
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
new Writer(barrier).start();
}
}
}
static class Writer2 extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer2(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
Log.d(TAG, "线程"+Thread.currentThread().getName()+"正在写入数据...");
try {
Thread.sleep(); //以睡眠来模拟写入数据操作
Log.d(TAG, "线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
try {
cyclicBarrier., TimeUnit.MILLISECONDS);//等待了指定的时间(2ms)发现第四个线程还没有达到barrier,就抛出异常并继续执行后面的任务
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
Log.d(TAG, Thread.currentThread().getName()+"所有线程写入完毕,继续处理其他任务...");
}
}
4.Semaphore示例
void testSemaphore() {
; //工人数
Semaphore semaphore = ); //机器数目
; i < N; i++)
new Worker(i, semaphore).start();
}
static class Worker extends Thread {
private int num;
private Semaphore semaphore;
public Worker(int num, Semaphore semaphore) {
this.num = num;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
Log.d(TAG,"工人" + this.num + "占用一个机器在生产...");
Thread.sleep();
Log.d(TAG,"工人" + this.num + "释放出机器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
java中的线程(4):常用同步类 CountDownLatch、CyclicBarrier和Semaphore的更多相关文章
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- Java中Collection、Map常用实现类研究分析
接口/实现类 描述 key是否可为null 为null是否报错 key是否重复 key重复是否报错 key是否和添加一致 是否线程安全 List 一组元素的集合 ArrayList 基于数组存储,读取 ...
- Java中创建线程的三种方式以及区别
在java中如果要创建线程的话,一般有3种方法: 继承Thread类: 实现Runnable接口: 使用Callable和Future创建线程. 1. 继承Thread类 继承Thread类的话,必须 ...
- 浅谈利用同步机制解决Java中的线程安全问题
我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...
- 【Java中的线程】java.lang.Thread 类分析
进程和线程 联想一下现实生活中的例子--烧开水,烧开水时是不是不需要在旁边守着,交给热水机完成,烧开水这段时间可以去干一点其他的事情,例如将衣服丢到洗衣机中洗衣服.这样开水烧完,衣服洗的也差不多了.这 ...
- 关于Java中的线程安全(线程同步)
java中的线程安全是什么: 就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问 什么叫 ...
- Java中的线程同步
Java 中的线程同步问题: 1. 线程同步: 对于访问同一份资源的多个线程之间, 来进行协调的这个东西. 2. 同步方法: 当某个对象调用了同步方法时, 该对象上的其它同步方法必须等待该同步方法执行 ...
- JAVA基础——Java 中必须了解的常用类
Java中必须了解的常用类 一.包装类 相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的,比如基本类型不 ...
- Java中的线程Thread总结
首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Threa ...
随机推荐
- IE6支持兼容max-height、min-height CSS样式
1.IE6支持max-height解决方法 - TOP IE6支持最大高度解决CSS代码: .yangshi{max-height:1000px;_height:expression((doc ...
- SQL语句学习积累·数据的操作
数据的操作 select 取表中前五条数据 select top 5 from table_name 取表中前50%的数据 select top 50 percent from table_name ...
- Java WEB中的HttpServletResponse数据传递
1.什么是HttpServletResponse 2.使用HttpServletResponse向浏览器发送数据及相关实例. 实例1:实现文件下载功能 实例2:实现验证码注册 实例3:实现页面3秒后跳 ...
- 编写高质量代码改善C#程序的157个建议——建议51:具有可释放字段的类型或拥有本机资源的类型应该是可释放的
建议51:具有可释放字段的类型或拥有本机资源的类型应该是可释放的 在建议50中,我们将C#中的类型分为:普通类型和继承了IDisposable接口的非普通类型.非普通类型除了包含那些托管资源的类型外, ...
- P1001
原创 问题描述: 当两个比较大的整数相乘时,可能会出现数据溢出的情形.为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法. 具体来说,首先以字符串的形式输入两个整数,每个整数的长度不会超过8位, ...
- [raspberry p3] suse wifi驱动加载
问题 raspberry pi3安装后发现wifi 启动不了, brcmf_sdio加载失败了,return error code为-110 处理方法 打开 /etc/dracut.conf.d/ra ...
- [.net 多线程]Monitor
Monitor 类通过向单个线程授予对象锁来控制对对象的访问.对象锁提供限制访问代码块(通常称为临界区)的能力.当一个线程拥有对象的锁时,其他任何线程都不能获取该锁.还可以使用 Monitor 来确保 ...
- .Net Core .Net Core V1.0 创建MVC项目
.Net Core V1.0 创建MVC项目 创建MVC项目有两种方式: 一.创建Web项目:(有太多没用的东西要去删太麻烦) 2.项目目录结构: 此种方法要注意的是,会创建好多个json文件,下面就 ...
- javascript 视频播放指定的时间段
javascript 视频播放指定的时间段 一.html5 vedio: //指定开始时间 player.currentTime=startPoint; player.play(); //使用事件来控 ...
- 如何设置linux支持上传的文件中文不乱吗
一.背景: 1.由于客户的需求,需要a链接打开的pdf文件,支持中文名称的 二.步骤 ①.查看当前编码 locale ②.编辑 vi /etc/profile 打开后结尾处添加 export LA ...