Java多线程之----CountDownLatch
2015-12-14 14:15
429 查看
有时候,会遇到这样一种情况,有多个任务,有一个主要任务需要等待其他子任务完成之后,才可以进行
而多线程中的CountDownLatch则提供了这样的功能,在初始化的时候,可以指定一个计数器,在每个子线程完成任务的时候减一,等到计数器为0的时候,那么,主线程才会进行
有这样的情景:要进行一次会议,会议要等到所有人都到齐了才可以开始,看下代码
public class CountDownLatchTest {
public static void main(String[] args) {
CountDownLatch conferenceBegin = new CountDownLatch(1);//计数器初始化为1
CountDownLatch conferenceEnd = new CountDownLatch(5);//计数器初始化为5
Conference conference = new Conference(conferenceBegin, conferenceEnd);
new Thread(conference).start();
for (int i = 0; i < 5; i++) {
Participant participant = new Participant(conferenceBegin, conferenceEnd, "参与者" + (i + 1));
new Thread(participant).start();
}
}
}
class Participant implements Runnable {
private CountDownLatch conferenceBegin;
private CountDownLatch conferenceEnd;
private String name;
public Participant(CountDownLatch conferenceBegin, CountDownLatch conferenceEnd, String name) {
this.conferenceBegin = conferenceBegin;
this.conferenceEnd = conferenceEnd;
this.name = name;
}
@Override
public void run() {
try {
conferenceBegin.await();// 使用await方法后,等到计数为0才继续执行
Thread.sleep((int) (Math.random() * 10) * 1000);
System.out.println(name + "进场");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
conferenceEnd.countDown();// 使用一次countDown方法,计数减一
}
}
}
class Conference implements Runnable {
private CountDownLatch conferenceEnd;
private CountDownLatch conferenceBegin;
public Conference(CountDownLatch conferenceBegin, CountDownLatch conferenceEnd) {
this.conferenceEnd = conferenceEnd;
this.conferenceBegin = conferenceBegin;
}
@Override
public void run() {
try {
System.out.println("会议准备开始,在" + conferenceEnd.getCount() + "个人到达后开始");
conferenceBegin.countDown();
conferenceEnd.await();
System.out.println("人数齐了,会议开始....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这就是CountDownLatch的简单用法,也可以用在这样的情景上:在程序开始的时候,需要执行一些初始化操作,在初始化操作都好了之后,才能进行另外的操作,那么此时也是可以使用CountDownLatch来完成这种功能
而多线程中的CountDownLatch则提供了这样的功能,在初始化的时候,可以指定一个计数器,在每个子线程完成任务的时候减一,等到计数器为0的时候,那么,主线程才会进行
有这样的情景:要进行一次会议,会议要等到所有人都到齐了才可以开始,看下代码
public class CountDownLatchTest {
public static void main(String[] args) {
CountDownLatch conferenceBegin = new CountDownLatch(1);//计数器初始化为1
CountDownLatch conferenceEnd = new CountDownLatch(5);//计数器初始化为5
Conference conference = new Conference(conferenceBegin, conferenceEnd);
new Thread(conference).start();
for (int i = 0; i < 5; i++) {
Participant participant = new Participant(conferenceBegin, conferenceEnd, "参与者" + (i + 1));
new Thread(participant).start();
}
}
}
class Participant implements Runnable {
private CountDownLatch conferenceBegin;
private CountDownLatch conferenceEnd;
private String name;
public Participant(CountDownLatch conferenceBegin, CountDownLatch conferenceEnd, String name) {
this.conferenceBegin = conferenceBegin;
this.conferenceEnd = conferenceEnd;
this.name = name;
}
@Override
public void run() {
try {
conferenceBegin.await();// 使用await方法后,等到计数为0才继续执行
Thread.sleep((int) (Math.random() * 10) * 1000);
System.out.println(name + "进场");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
conferenceEnd.countDown();// 使用一次countDown方法,计数减一
}
}
}
class Conference implements Runnable {
private CountDownLatch conferenceEnd;
private CountDownLatch conferenceBegin;
public Conference(CountDownLatch conferenceBegin, CountDownLatch conferenceEnd) {
this.conferenceEnd = conferenceEnd;
this.conferenceBegin = conferenceBegin;
}
@Override
public void run() {
try {
System.out.println("会议准备开始,在" + conferenceEnd.getCount() + "个人到达后开始");
conferenceBegin.countDown();
conferenceEnd.await();
System.out.println("人数齐了,会议开始....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//会议准备开始,在5个人到达后开始 //参与者4进场 //参与者2进场 //参与者5进场 //参与者3进场 //参与者1进场 //人数齐了,会议开始....结果如上,在Paticipant线程中,调用了begin的await方法,那么在begin的计数器为0之前,程序不会继续向下运行,在Conference线程执行的时候,首先让begin的计数器减一,由于初始化为1,那么这个操作之后,begin的计数器就为0了,则Paticipant线程就可以继续运行了,每个线程运行完后,都会调用countDowm方法,当5个线程运行完后,end的计数器也为0了,此时Conference中由于调用await方法后面的代码就可以继续运行了
这就是CountDownLatch的简单用法,也可以用在这样的情景上:在程序开始的时候,需要执行一些初始化操作,在初始化操作都好了之后,才能进行另外的操作,那么此时也是可以使用CountDownLatch来完成这种功能
相关文章推荐
- Eclipse Mars4.5.1中安装运行 jboss7.1.1
- java中static{}语句块详解
- Java查询大文本
- Java查询大文本
- 学习 java 编程语言两个月来的感受
- java类加载器,收藏的几篇博文
- 如何用Java实现两个文件的拼接
- java的IO流以及复制粘贴操作
- 归并排序 Java
- 最好的8个 Java RESTful 框架
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- 业务需要,IOS转到JAVA 安卓端开发,开始记录一些小知识点
- Merge K Sorted List(含Merge Two Sorted LIst) leetcode java
- JAVA-原型模式
- 对java的一些认识
- Java开发中的23种设计模式详解(转)
- struts2实现多文件上传
- spring框架(三)junit单元测试
- java 泛型
- Spring学习笔记(十三):jsp、freemarker、velocity的区别