java高级---->Thread之CountDownLatch的使用
CountDownLatch是JDK 5+里面闭锁的一个实现,允许一个或者多个线程等待某个事件的发生。今天我们通过一些实例来学习一下它的用法。
CountDownLatch的简单使用
CountDownLatch的简单介绍:
CountDownLatch类是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞程序继续执行
CountDownLatch是一个倒计数的锁存器,当计数减至0时触发特定的事件。
CountDownLatch被用来同步一个或多个任务,强制它们等待由其他任务执行的一组操作完成。你可以向CountDownLatch对象设置一个初始计数值,任何在这个对象上调用wait()方法都将阻塞,直至这个计数值达到0。其他任务在结束工作时,可以在该对象上调用凑你countDown()来减小这个计数值。CountDownLatch被设计为只触发一次,计数值不能被重置。如果你需要能够重置计数值的版本,则可以使用CyclicBarrier。
以下是jdk文档上的两个例子,我们可以学习一下。
一、开始信号,阻止任何工人进行,直到司机准备好他们继续进行
package com.linux.huhx.concurreny; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; public class Driver1 {
public static void main(String[] args) throws Exception {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(5);
for (int i = 0; i < 5; ++i) // create and start threads
new Thread(new TaskWorker(startSignal, doneSignal)).start();
System.out.println("countDown before."); // don't let run yet
startSignal.countDown(); // let all threads proceed
TimeUnit.SECONDS.sleep(1);
System.out.println("await before");
/**
* 1、由于doneSignal里面的初始count=5,所以主线程在此会阻塞。
* 2、当所有的子线程执行完(doneSignal.countDown())之后,此时的count=0。所以后面代码可以继续执行。
*/
doneSignal.await();
System.out.println("await after");
} private static class TaskWorker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal; public TaskWorker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
} @Override
public void run() {
try {
/**
* 1、刚进来的时候,由于startSignal的count=1。所以await()方法阻塞于此。
* 2、当主线程执行了startSignal.countDown();此时的startSignal的count=0。所以子线程可以正常运行。
*/
startSignal.await();
doSomeWork();
doneSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void doSomeWork() {
System.out.println("in run method: " + Thread.currentThread().getName());
}
}
}
执行的结果如下:子线程的执行顺序不固定
countDown before.
in run method: Thread-
in run method: Thread-
in run method: Thread-
in run method: Thread-
in run method: Thread-
await before
await after
调用countDown()的任务在产生这个调用时并没有阻塞,只有对await()的调用会被阻塞,直至计数值到达0。
二、完成信号,允许司机等到所有工人完成为止
package com.linux.huhx.concurreny; import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Driver2 {
public static void main(String[] args) throws Exception {
CountDownLatch doneSignal = new CountDownLatch(5);
ExecutorService service = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; ++i) // create and start threads
service.execute(new WorkerRunnable(doneSignal, i));
System.out.println("await before");
doneSignal.await();
System.out.println("await after");
service.shutdown();
} private static class WorkerRunnable implements Runnable {
private final CountDownLatch doneSignal;
private final int i; public WorkerRunnable(CountDownLatch doneSignal, int i) {
this.doneSignal = doneSignal;
this.i = i;
} @Override
public void run() {
doWork(i);
try {
Thread.sleep(new Random().nextInt(1000));
doneSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
} private void doWork(int i) {
System.out.println("in run method: " + i + " " + Thread.currentThread().getName());
}
}
}
运行的结果如下:子线程的执行顺序不固定
await before
in run method: pool--thread-
in run method: pool--thread-
in run method: pool--thread-
in run method: pool--thread-
in run method: pool--thread-
await after
友情链接
java高级---->Thread之CountDownLatch的使用的更多相关文章
- java高级---->Thread之CyclicBarrier的使用
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).今天我们就学习一下CyclicBarrier的用法. Cycl ...
- java高级---->Thread之ScheduledExecutorService的使用
ScheduledExecutorService的主要作用就是可以将定时任务与线程池功能结合使用.今天我们来学习一下ScheduledExecutorService的用法.我们都太渺小了,那么容易便湮 ...
- java高级---->Thread之ExecutorService的使用
今天我们通过实例来学习一下ExecutorService的用法.我徒然学会了抗拒热闹,却还来不及透悟真正的冷清. ExecutorService的简单实例 一.ExecutorService的简单使用 ...
- java高级---->Thread之Phaser的使用
Phaser提供了动态增parties计数,这点比CyclicBarrier类操作parties更加方便.它是jdk1.7新增的类,今天我们就来学习一下它的用法.尘埃落定之后,回忆别来挑拨. Phas ...
- java高级---->Thread之CompletionService的使用
CompletionService的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与处理任务分离开来进行处理.今天我们通过实例来学习一下CompletionServi ...
- java高级---->Thread之BlockingQueue的使用
今天我们通过实例来学习一下BlockingQueue的用法.梦想,可以天花乱坠,理想,是我们一步一个脚印踩出来的坎坷道路. BlockingQueue的实例 官方文档上的对于BlockingQueue ...
- java高级---->Thread之Exchanger的使用
Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据.今天我们就通过实例来学习一下Exchanger的用法. Exchanger的简单实例 Exchanger是 ...
- java高级---->Thread之FutureTask的使用
FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行.今天我们通过实例来学习一下FutureTask的 ...
- java高级---->Thread之Condition的使用
Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set ...
随机推荐
- [3G/4G]3G/4G模块开发
转自:http://mywutuobang.blog.sohu.com/260073467.html 一. 修改内核支持3G模块,一般内核需要枚举相关的通讯模块,其接口为串口,其数据接口和通讯接口枚举 ...
- EcmaScript对象克隆之谜
先谈谈深拷贝 如何在js中获得一个克隆对象,可以说是喜闻乐见的话题了.相信大家都了解引用类型与基本类型,也都知道有种叫做深拷贝的东西,传说深拷贝可以获得一个克隆对象!那么像我这样的萌新自然就去学习了一 ...
- MongoDB自动删除过期数据--TTL索引
前序: 由于公司业务需求,对于3个月前的过期数据需要进行删除动作,以释放空间和方便维护 本来想的是使用crontab写个脚本定时执行,但是看到Mongo本身就有自动删除过期数据的功能,所以还是用一 ...
- 基于Java的四大开源测试工具
摘要:成功的应用程序离不开测试人员和QA团队反复地测试,应用程序在进行最后的部署之前,需要通过测试来确保它的负载管理能力以及在特殊情况下的工作条件和工作加载情况. %R[)vA t]N0 测试是应用程 ...
- Linux Linux常用命令三
在Vim中可以直接查看文件编码 :set fileencoding 即可显示文件编码格式. touch 创建文件或修改文件时间 touch [options] file-list 参数 file-li ...
- UML总结--总体架构
架构图(一): 架构图(二): 转自:http://blog.csdn.net/lsh6688/article/details/5931706
- Spring 4 官方文档学习(十)数据访问之ORM
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html 占位用,暂略.
- C# HttpClientHelper请求
public class HttpClientHelper { /// <summary> /// get请求 /// </summary> /// <param nam ...
- CentOS基础命令大全
1.关机 (系统的关机.重启以及登出 ) 的命令 shutdown -h now 关闭系统(1) init 0 关闭系统(2) telinit 0 关闭系统(3) shutdown -h hours: ...
- 【Java面试题】11 什么是内部类?Static Nested Class 和 Inner Class的不同。
Inner Class(内部类)定义在类中的类. (一般是JAVA的说法) Nested Class(嵌套类)是静态(static)内部类.(一般是C++的说法)静态内部类:1 创建一个static内 ...