CountDownLatch与thread-join()的区别
今天学习CountDownLatch这个类,作用感觉和join很像,然后就百度了一下,看了他们之间的区别。所以在此记录一下。
首先来看一下join,在当前线程中,如果调用某个thread的join方法,那么当前线程就会被阻塞,直到thread线程执行完毕,当前线程才能继续执行。join的原理是,不断的检查thread是否存活,如果存活,那么让当前线程一直wait,直到thread线程终止,线程的this.notifyAll 就会被调用。
我们来看一下这个应用场景:假设现在公司有三个员工A,B,C,他们要开会。但是A需要等B,C准备好之后再才能开始,B,C需要同时准备。我们先用join模拟上面的场景。
Employee.java:
public class Employee extends Thread{
private String employeeName;
private long time;
public Employee(String employeeName,long time){
this.employeeName = employeeName;
this.time = time;
}
@Override
public void run() {
try {
System.out.println(employeeName+ "开始准备");
Thread.sleep(time);
System.out.println(employeeName+" 准备完成");
} catch (Exception e) {
e.printStackTrace();
}
}
}
JoinTest.java:
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
Employee a = new Employee("A", 3000);
Employee b = new Employee("B", 3000);
Employee c = new Employee("C", 4000);
b.start();
c.start();
b.join();
c.join();
System.out.println("B,C准备完成");
a.start();
}
}
最后输出结果如下:
C开始准备
B开始准备
B 准备完成
C 准备完成
B,C准备完成
A开始准备
A 准备完成
可以看到,A总是在B,C准备完成之后才开始执行的。
CountDownLatch中我们主要用到两个方法一个是await()方法,调用这个方法的线程会被阻塞,另外一个是countDown()方法,调用这个方法会使计数器减一,当计数器的值为0时,因调用await()方法被阻塞的线程会被唤醒,继续执行。
接下来,我们用CountDownLatch来模拟一下。
Employee.java:
public class Employee extends Thread{
private String employeeName;
private long time;
private CountDownLatch countDownLatch;
public Employee(String employeeName,long time, CountDownLatch countDownLatch){
this.employeeName = employeeName;
this.time = time;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
System.out.println(employeeName+ "开始准备");
Thread.sleep(time);
System.out.println(employeeName+" 准备完成");
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
CountDownLatchTest.java:
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(2);
Employee a = new Employee("A", 3000,countDownLatch);
Employee b = new Employee("B", 3000,countDownLatch);
Employee c = new Employee("C", 4000,countDownLatch);
b.start();
c.start();
countDownLatch.await();
System.out.println("B,C准备完成");
a.start();
}
}
输出结果如下:
B开始准备
C开始准备
B 准备完成
C 准备完成
B,C准备完成
A开始准备
A 准备完成
上面可以看到,CountDownLatch与join都能够模拟上述的场景,那么他们有什么不同呢?这时候我们试想另外一个场景就能看到他们的区别了。
假设A,B,C的工作都分为两个阶段,A只需要等待B,C各自完成他们工作的第一个阶段就可以执行了。
我们来修改一下Employee类:
public class Employee extends Thread{
private String employeeName;
private long time;
private CountDownLatch countDownLatch;
public Employee(String employeeName,long time, CountDownLatch countDownLatch){
this.employeeName = employeeName;
this.time = time;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
System.out.println(employeeName+ " 第一阶段开始准备");
Thread.sleep(time);
System.out.println(employeeName+" 第一阶段准备完成");
countDownLatch.countDown();
System.out.println(employeeName+ " 第二阶段开始准备");
Thread.sleep(time);
System.out.println(employeeName+" 第二阶段准备完成");
} catch (Exception e) {
e.printStackTrace();
}
}
}
CountDownLatchTest类不需要做修改,输出结果入下:
B 第一阶段开始准备
C 第一阶段开始准备
B 第一阶段准备完成
B 第二阶段开始准备
C 第一阶段准备完成
C 第二阶段开始准备
B,C第一阶段准备完成
A 第一阶段开始准备
B 第二阶段准备完成
A 第一阶段准备完成
A 第二阶段开始准备
C 第二阶段准备完成
A 第二阶段准备完成
从结果可以看出,A在B,C第一阶段准备完成的时候就开始执行了,不需要等到第二阶段准备完成。这种场景下,用join是没法实现的。
总结:调用join方法需要等待thread执行完毕才能继续向下执行,而CountDownLatch只需要检查计数器的值为零就可以继续向下执行,相比之下,CountDownLatch更加灵活一些,可以实现一些更加复杂的业务场景。
参考:https://blog.csdn.net/zhutulang/article/details/48504487
CountDownLatch与thread-join()的区别的更多相关文章
- Thread.join(), CountDownLatch、CyclicBarrier和 Semaphore区别,联系及应用
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法, 由于 ...
- JAVA多线程之CountDownLatch与join的区别
首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...
- CountDownLatch与join的区别和联系
首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...
- 多线程进阶---Thread.join()/CountDownLatch.await() /CyclicBarrier.await()
Thread.join() CountDownLatch.await() CyclicBarrier.await() 三者都是用来控制程序的"流动" 可以让程序"堵塞&q ...
- CyclicBarrier、CountDownLatch、Callable、FutureTask、thread.join() 、wait()、notify()、Condition
CyclicBarrier使用: import java.util.Random; import java.util.concurrent.BrokenBarrierException; import ...
- c# 大白话告诉你Thread的Sleep和Join的区别
我们的程序默认会有两个线程,一个是主线程,一个是负责垃圾回收的线程.如果代码不使用多线程,就只有主线程这一条干道.1.在主线程中调用Thread.Sleep(1000),表示主线程阻塞自己1秒.2.在 ...
- thread.join 从异步执行变成同步
Java的线程模型为我们提供了更好的解决方案,这就是join方法.在前面已经讨论过,join的功能就是使用线程 从异步执行变成同步执行 当线程变成同步执行后,就和从普通的方法中得到返回数据没有什么区别 ...
- Thread.join()分析方法
API: join public final void join() throws InterruptedException 等待该线程终止. 抛出: InterruptedException - 假 ...
- sleep、yield、wait、join的区别(阿里面试)
1. Thread.sleep(long) 和Thread.yield()都是Thread类的静态方法,在调用的时候都是Thread.sleep(long)/Thread.yield()的方式进行调 ...
- 颠覆我的Thread.join()
学而时习之,不亦说乎! --<论语> 为什么说是颠覆? 1)任何对象都可以作为锁对象,锁对象的行为都是一样的吗?之前我一直认为锁对 ...
随机推荐
- Mycat 分片规则详解--一致性hash分片
实现方式:基于hash算法的分片中,算法内部是把记录分片到一种叫做"bucket"(hash桶)的内部算法结构中的,然后hash桶与实际的分片节点一一对应,从此实现了分片.路由的功 ...
- 【JS】 Javascript 入门
javascript **********本章大量示例和内容引用自w3cschool的javascript教程************** 本来已经快写完90%左右了,结果不小心跑了个js,不小心把浏 ...
- 移动端H5地图矢量SHP网格切分打包方案
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 与离线瓦片方案一样,同样是为了解决移动端网速和流量问题,但是却 ...
- <经验杂谈>C#使用AES加密解密的简单介绍
AES 算法是基于置换和代替的.置换是数据的重新排列,而代替是用一个单元数据替换另一个.AES 使用了几种不同的技术来实现置换和替换. 以下是我自己用c#研究出来算法Code: /// <sum ...
- Java基础学习笔记四 Java基础语法
数组 数组的需求 现在需要统计某公司员工的工资情况,例如计算平均工资.最高工资等.假设该公司有50名员工,用前面所学的知识完成,那么程序首先需要声明50个变量来分别记住每位员工的工资,这样做会显得很麻 ...
- Java读取word中表格
因为要新建一个站,公司要把word表格的部分行列存到数据库中.之前用java操作过excel,本来打算用java从word表格中读取数据,再存到数据库中,结果因为权限不够,无法访问公司要写的那个数据库 ...
- 网络1712--c语言第一次作业总结
1.作业亮点 1.1大家均能较为独立自主地完成第一次c语言作业,无明显抄袭现象 1.2 以下几位同学博文写的较为优秀,可作为范例供大家参考 田亚琴--态度端正,及时回复评论并及时完善修改博文 戴洁-- ...
- 2017-2018-1 Java演绎法 第四五周 作业
团队任务:撰写<需求规格说明书> 团队组长:袁逸灏 本次编辑:刘伟康 流程.分工.比例 (比例按照任务的费时.难度和完成情况估算) 流程 确定任务 -→ 分配任务 -→ 各组员完成各自任务 ...
- 【iOS】单元测试
iOS单元测试(作用及入门提升) 字数1704 阅读16369 评论26 喜欢247 由于只是一些简单实用的东西,学学还是挺不错的.其实单元测试用的好,开发起来也会快很多.单元测试对于我目前来说,就是 ...
- 201621123043 《Java程序设计》第7周学习总结
1. 本周学习总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 事件:用户的操作. 事件源:产生事件的组件. 事件监听程序:对事件进行处理的操作所引发的相关 ...