多线程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完 ...
随机推荐
- ACM 海贼王之伟大航路(深搜剪枝)
"我是要成为海贼王的男人!" 路飞他们伟大航路行程的起点是罗格镇,终点是拉夫德鲁(那里藏匿着"唯一的大秘宝"--ONE PIECE).而航程中间,则是各式各样的 ...
- 我的JS 中级学习篇
在codefordream上进入中级学习后,感觉立马从js的基础学习往前跳了好远,上面的东西好像都是第一次看到一样.这时候才发现,说来也曾接触过js,但是这时候才发现对js的认识就停在知道两点:js中 ...
- 详解JavaScript闭包
要想完全明白JavaScript的闭包,要先明白js中的一些基础原理,然后我再给出一些例子来讲解闭包. 在执行JavaScript时会创建一个执行环境(excution context),执行环境定义 ...
- 利用jink的驱动软件j-flash 合并两个hex的方法,bootloader+app
由于前几天要给工厂app和bootloader的hex的文件,网上很多都是bin的合并方法,bin的方法不再赘述,相信大家都能找到,现在将hex合并的方法写下来: 第一步:先打开第一个hex文件, 第 ...
- Redis【第二篇】集群搭建
第一步:准备 1.安装包 ruby-2.4.0.tar.gz rubygems-2.6.10.tgz zlib-1.2.11.tar.gz redis-3.3.2.gem 2. 架构: 名称 IP 端 ...
- 2017.3.3自测j纠错题.
解析: 在jUery中,他的背景颜色依次是红色,绿色,蓝色. 改变的是整个主体部分.<dody></body>. 单击. 2. 解析: 操作元素: html() 获取第 ...
- 2017-02-23 switch case 循环语句
另一个分支语句:switch..case.. switch(变量){ case 值:代码段;break; case 值:代码段;break; ... default:代码段;b ...
- JS入门(三)
数据的类型转换: 之前提到过,js中数据类型分两种, 基本数据类型string number boolean undefined null 复杂数据类型 对象 Date Array ...
- 1934: [Shoi2007]Vote 善意的投票
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 1174 Solved: 723[Submit][S ...
- UIImagePickerController拍照/相册/录像/本地视频
1.导入系统库 #import <MobileCoreServices/MobileCoreServices.h> 2.遵守协议 <UIImagePickerControllerDe ...