多线程CountDownLatch和Join
如果现在有五个线程A、B、C、D、E,请问如何用E线程用于统计A、B、C、D四个线程的结果?
题意需要用E线程统计A、B、C、D四个线程,也就是说E线程必须要等到前面四个线程运行结束之后才能执行。那么如何使用E线程来统计前面四个线程的结果呢?
下面介绍两种实现方法:
一、CountDownLatch
CountDownLatch是一种java.util.concurrent包下一个同步工具类,它允许一个或多个线程等待直到在其他线程中一组操作执行完成。
我们可以将CountDownLatch看作一个计数器,可以给定其一个数来对其进行初始化。当它计数的值变为0时,才可以执行后续的步骤。
public CountDownLatch(int count)
CountDownLatch有两个方法是我们常用的:await();和countDown();
await()函数用于阻塞当前线程直到CountDownLatch的计数值变为0;
countDown()方法用于将当前CountDownLatch的计数值减1;
简单的介绍了CountDownLatch的作用和用法之后,我们看下如下的代码:
import java.util.concurrent.CountDownLatch;
public class Test1{
public static void main(String[] args) throws InterruptedException {
int number = 3;
CountDownLatch latch = new CountDownLatch(number); for(int i=0;i<3;i++){
ThreadDemo demo = new ThreadDemo(latch);
demo.start();
System.out.println(i);
}
latch.await();
System.out.println("Check it Out");
}
} class ThreadDemo extends Thread{ private CountDownLatch latch; public ThreadDemo(CountDownLatch latch){
this.latch = latch;
} public void run(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}
我们首先创建了一个CountDownLatch对象给定一个number将其初始化,需要注意的是当前CountDownLatch对象的值减为0之后,该对象便失去了作用。
同时我们提供了继承自Thread的ThreadDemo类,它包含了一个CountDownLatch对象。当我们创建ThreadDemo对象时,会将CountDowmLatch对象注入其中。
在TreadDemo类的run()方法中,我们执行了两步动作:延迟5秒后将CountDownLatch的计数值减1。
在main函数中,我们利用for循环创建了三个ThreadDemo对象并执行他们的run()方法。添加和不添加latch.await()语句将会得到两种执行结果。
1、添加latch.await()语句
执行结果:
0
1
2
Check it Out
我们会发现0 1 2几乎是同时打印出来的,但是“Check it Out”大概等待了5秒左右的时间后才打印,这说明了其实“Check it Out”是等待前面三个线程执行完countDown()方法之后将latch的值减为0之后才执行的。
2、无latch.await()语句
执行结果:
0
1
2
Check it Out
观察运行结果我们会发现,0 1 2和“Check it Out”几乎是同时出现的,也就是说“Check it Out”并没有等待前面三个线程执行完成之后才执行。
CountDowLlatch的用途即是让一组线程先执行,知道countdownlatch对象的计数值到0后,让后续的线程继续执行。
二、join方法实现
事实上,join方法也可以实现同样的效果!代码如下:
import java.util.concurrent.CountDownLatch;
public class Test{
public static void main(String[] args) throws InterruptedException {
int number = 3;
CountDownLatch latch = new CountDownLatch(number);
ThreadDemo thread1 = new ThreadDemo(1);
ThreadDemo thread2 = new ThreadDemo(2);
thread1.start();
thread1.join();
System.out.println("----");
thread2.start();
thread2.join();
System.out.println("main is end!"); }
} class ThreadDemo extends Thread{
private int number;
public ThreadDemo(int number){
this.number = number;
}
public void run(){
System.out.println("Thread"+number+" is running");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread"+number+"is end");
}
}
运行结果如下:
Thread1 is running
Thread1is end
----
Thread2 is running
Thread2is end
main is end!
可以看到thread1阻塞了thread2,只有当thread1和thread2均执行结束后,main方法才能继续执行。如果想要thread1和thread2同时执行的话,只需要做如下简单的变动。
thread1.start();
thread1.join();
thread2.start();
thread2.join(); System.out.println("main is end!");
运行结果如下:
Thread1 is running
Thread2 is running
Thread1is end
Thread2is end
main is end!
因此,如果我们需要某些线程等待指定任务执行完毕之后执行,选择join方法也是一种选择;
多线程CountDownLatch和Join的更多相关文章
- 关于python多线程编程中join()和setDaemon()的一点儿探究
关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧. 首先是编写实验的基础代码,创建一个名为MyThread的 ...
- JAVA多线程之CountDownLatch与join的区别
首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...
- CountDownLatch与join的区别和联系
首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...
- 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例
java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...
- 多线程进阶---Thread.join()/CountDownLatch.await() /CyclicBarrier.await()
Thread.join() CountDownLatch.await() CyclicBarrier.await() 三者都是用来控制程序的"流动" 可以让程序"堵塞&q ...
- 跟着ZooKeeper学Java——CountDownLatch和Join的使用
在阅读ZooKeeper的源码时,看到这么一个片段,在单机模式启动的时候,会调用下面的方法,根据zoo.cfg的配置启动单机版本的服务器: public void runFromConfig(Serv ...
- Java多线程--wait和join
首先从公司一道笔试题开始 package test; public class Test implements Runnable { public int i = 0; @Override publi ...
- Java多线程-CountDownLatch、CyclicBarrier、Semaphore
上次简单了解了多线程中锁的类型,今天要简单了解下多线程并发控制的一些工具类了. 1. 概念说明: CountDownLatch:相当于一个待执行线程计数器,当计数减为零时表示所有待执行线程都已执行完毕 ...
- 并发编程大师系列之:CountDownLatch和Join
业务场景描述:假设一条流水线上有三个工作者:worker1,worker2,worker3.有一个任务的完成需要他们三者协作完成,worker3可以开始这个任务的前提是worker1和worker2完 ...
随机推荐
- [solr] - solr5.2.1环境搭建 - 使用solr自带的jetty服务器
solr除了使用tomcat作为容器外,还可以使用其他的常用容器,比如jetty,jboos等,而且solr自身就自带jetty服务器,那么现在就solr自带的jetty服务器进行安装操作.由于sol ...
- 解决HTML导出Excel表数字变成科学计数法
- js 中导出excel 较长数字串会变成科学计数法 在做项目中,碰到如题的问题.比如要将居民的信息导出到excel中,居民的身份证号码因为长度过长(大于10位),excel会自动的将过长的数字串转 ...
- 配置opencv环境
包含目录:解决代码报错问题 F:\ndk\opencv-windows\opencv\build\include;F:\ndk\opencv-windows\opencv\sources\includ ...
- Java实现OOP(面向对象编程)
一.对象的综述 面向对象编程(OOP)具有多方面的吸引力.对管理人员,它实现了更快和更廉价的开发与维护过程.对分析与设计人员,建模处理变得更加简单,能生成清晰.易于维护的设计方案.对程序员,对象模型显 ...
- Java重写equals()和hashCode()
1.何时需要重写equals() 当一个类有自己特有的 ”逻辑相等”概念(不同于对象身份的概念). 2.设计equals() [1]使用instanceof操作符检查 ”实参是否为正确的类型”. [2 ...
- 架构师之路——里氏替换原则LSP
定义: 如果对每一个对类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型. 内容: 里氏替换原则通 ...
- 每天一个linux命令(52)--wc命令
Linux 系统中的 wc(word count)命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出 1.命令格式: wc [选项] 文件 2.命令功能: 统计指定文件中的字节数.字 ...
- ThinkPHP项目总结
1.当你 require ThinkPHP之后,会自动在App目录下生成 common, Home, Runtime 三个文件夹. 2.输入网址 http://localhost/blog/app/i ...
- RabbitMQ(从安装到使用)
RabbitMQ 一,RabbitMQ简单介绍: RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Messa ...
- Java设计模式之《代理模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6525527.html 代理模式算是我接触较早的模式,代理就是中介,中间人.法律上也有代理, ...