今天学习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()的区别的更多相关文章

  1. Thread.join(), CountDownLatch、CyclicBarrier和 Semaphore区别,联系及应用

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法, 由于 ...

  2. JAVA多线程之CountDownLatch与join的区别

    首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...

  3. CountDownLatch与join的区别和联系

    首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...

  4. 多线程进阶---Thread.join()/CountDownLatch.await() /CyclicBarrier.await()

    Thread.join() CountDownLatch.await() CyclicBarrier.await() 三者都是用来控制程序的"流动" 可以让程序"堵塞&q ...

  5. CyclicBarrier、CountDownLatch、Callable、FutureTask、thread.join() 、wait()、notify()、Condition

    CyclicBarrier使用: import java.util.Random; import java.util.concurrent.BrokenBarrierException; import ...

  6. c# 大白话告诉你Thread的Sleep和Join的区别

    我们的程序默认会有两个线程,一个是主线程,一个是负责垃圾回收的线程.如果代码不使用多线程,就只有主线程这一条干道.1.在主线程中调用Thread.Sleep(1000),表示主线程阻塞自己1秒.2.在 ...

  7. thread.join 从异步执行变成同步

    Java的线程模型为我们提供了更好的解决方案,这就是join方法.在前面已经讨论过,join的功能就是使用线程 从异步执行变成同步执行 当线程变成同步执行后,就和从普通的方法中得到返回数据没有什么区别 ...

  8. Thread.join()分析方法

    API: join public final void join() throws InterruptedException 等待该线程终止. 抛出: InterruptedException - 假 ...

  9. sleep、yield、wait、join的区别(阿里面试)

    1.  Thread.sleep(long) 和Thread.yield()都是Thread类的静态方法,在调用的时候都是Thread.sleep(long)/Thread.yield()的方式进行调 ...

  10. 颠覆我的Thread.join()

    学而时习之,不亦说乎!                              --<论语> 为什么说是颠覆? 1)任何对象都可以作为锁对象,锁对象的行为都是一样的吗?之前我一直认为锁对 ...

随机推荐

  1. 笔记:Struts 2.3.31 配置说明

    复制文件到站点的 WEB-INF\lib 目录,文件列表如下,黄色突出显示的是必须加入的核心包 struts2-core-2.3.31.jar:struts2 的核心库 xwork-core-2.3. ...

  2. canvas---HTML5新特性

    画圆及填充文字<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <ti ...

  3. java中equals相同,hashcode一定相同ma

    一.jdk中equals和hashcode的定义和源码进行分析 1.java.lang.Object中对equals()方法的定义 java.lang.Object中对hashCode()方法的定义 ...

  4. python提示import XX 不存在,如何排查错误

    1.如何确定文件夹是一个包, 检查包中是否有__init__.py 文件, 在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录 ...

  5. (转)SQLite内置函数

    一.聚合函数: SQLite中支持的聚合函数在很多其他的关系型数据库中也同样支持,因此我们这里将只是给出每个聚集函数的简要说明,而不在给出更多的示例了.这里还需要进一步说明的是,对于所有聚合函数而言, ...

  6. lua对多个精灵执行一系列动作,延时失效

    function MainPlayerCards:sendCards() local winSize = cc.Director:getInstance():getWinSize() local nS ...

  7. drbd(二):配置和使用

    本文目录:1.drbd配置文件2.创建metadata区并计算metadata区的大小3.启动drbd4.实现drbd主从同步5.数据同步和主从角色切换6.drbd脑裂后的解决办法7.drbd多卷组配 ...

  8. I Know Alpha冲刺随笔集

    Alpha冲刺 Day1 Alpha冲刺 Day2 Alpha冲刺 Day3 Alpha冲刺 Day4 Alpha冲刺 Day5 Alpha冲刺 Day6 Alpha冲刺 Day7 Alpha冲刺 D ...

  9. 听翁恺老师mooc笔记(12)--结构中的结构

    结构数组: 和C语言中的int,double一样,一旦我们做出一个结构类型,就可以定义这个结构类型的变量,也可以定义这个结构类型的数组.比如下面这个例子: struct date dates[100] ...

  10. Beta 第三天

    今天遇到的困难: 组员对github极度的不适应 github的版本控制和协同化编程确实操作起来需要一定的熟练度,我们缺乏这种熟练度 Android Studio版本不一致项目难以打开的问题仍然无法解 ...