java多线程中CountDownLatch和join的使用
在工作中,我们经常需要和多线程打交道,简单说明一个场景,在工厂流水线上有2条流水线,流水线同时开工生产零件,但是每个零件生产时间不一样,只有等到两个零件都生产完毕之后才能开始总组装。那我们很快想到join就能做到。例如子线程thread调用了join,那么在子线程thread还存活的时候,让当前线程wait,直到thread死亡,就会调用当前线程的notifyAll方法。
简单用一个小例子来说明一下,现在有两个工作线程,分别给一个随机的工作时间t,然后在线程中给这个随机的工作时间+1s得到时间T;等到两个工作线程执行完毕之后,我们再执行第三个线程,这两个时间T加起来就是第三个线程的工作时间。那看一下代码和执行结果。
public class JoinTest {public static void main(String[] args) {WorkThread work_one = new WorkThread("work one", new Random().nextInt(10)); WorkThread work_two = new WorkThread("work two", new Random().nextInt(10)); work_one.start(); work_two.start(); try {work_one.join(); work_two.join(); } catch (InterruptedException e) {e.printStackTrace(); }System.out.println("准备工作做完,可以开始干正事"); WorkThread work_mian = new WorkThread("work main", work_one.getWorkTime() + work_two.getWorkTime()); work_mian.start(); }private static class WorkThread extends Thread {private int WorkTime; private String WorkName; public int getWorkTime() {return WorkTime; }public WorkThread(String WorkName, int WorkTime) {this.WorkName = WorkName; this.WorkTime = WorkTime; System.out.println(WorkName + " initialize time = " + WorkTime); }@Override public void run() {try {System.out.println(WorkName + " start work..."); WorkTime = WorkTime + 1; Thread.sleep(1000 * WorkTime); System.out.println(WorkName + " complete work WorkTime = " + WorkTime); } catch (InterruptedException e) {e.printStackTrace(); System.out.println(WorkName + " error work..."); }}} }
执行结果:
work one initialize time = 3
work two initialize time = 4
work one start work...
work two start work...
work one complete work WorkTime = 4
work two complete work WorkTime = 5
准备工作做完,可以开始干正事
work main initialize time = 9
work main start work...
work main complete work WorkTime = 10
那在jdk1.5之后,我们引入了CountDownLatch,CountDownLatch的原理就是先初始化执行线程的个数,执行完我们的工作之后就手动减一,等到读取的个数为0的时候,就开始总的工作。我们也用同样的场景来写一份代码。
public class CountDownLatchTest {public static void main(String[] args) {CountDownLatch countDownLatch = new CountDownLatch(2); WorkThread work_one = new WorkThread("work one", new Random().nextInt(10), countDownLatch); WorkThread work_two = new WorkThread("work two", new Random().nextInt(10), countDownLatch); work_one.start(); work_two.start(); //等待结果 try {countDownLatch.await(); System.out.println("准备工作做完,可以开始干正事"); WorkThread work_main = new WorkThread("work main", work_one.getWorkTime() + work_two.getWorkTime(), null); work_main.start(); } catch (InterruptedException e) {e.printStackTrace(); }}private static class WorkThread extends Thread {private int WorkTime; private String WorkName; private CountDownLatch countDownLatch; public int getWorkTime() {return WorkTime; }public WorkThread(String WorkName, int WorkTime, CountDownLatch countDownLatch) {this.WorkName = WorkName; this.WorkTime = WorkTime; this.countDownLatch = countDownLatch; System.out.println(WorkName + " initialize time = " + WorkTime); }@Override public void run() {try {System.out.println(WorkName + " start work..."); WorkTime = WorkTime + 1; Thread.sleep(1000 * WorkTime); System.out.println(WorkName + " complete work WorkTime = " + WorkTime); //工作完成后减一 if (countDownLatch != null) {countDownLatch.countDown(); }} catch (InterruptedException e) {e.printStackTrace(); System.out.println(WorkName + " error work..."); }}} }
附上执行结果:
work one initialize time = 7
work two initialize time = 8
work one start work...
work two start work...
work one complete work WorkTime = 8
work two complete work WorkTime = 9
准备工作做完,可以开始干正事
work main initialize time = 17
work main start work...
work main complete work WorkTime = 18
当然为什么要提供CountDownLatch呢,不是有join就够了吗。那我们看下第二个场景,这个是join做不到的。因为CountDownLatch带有计数器。比如有一个会议,每个人都要在会议上做笔记,那我们现在由于会议需要提前进行,只要人到了就开始会议,不需要花几分钟带上笔记本,会议之后再做笔记都行。这个时候CountDownLatch就能使用了。我们用代码看一下。
public class CountDownLatchTest {public static void main(String[] args) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(10); for (int i = 0; i < 10; i++) {new WorkThread(String.valueOf(i),new Random().nextInt(10),countDownLatch).start(); }countDownLatch.await(); System.out.println("会议开始,大家没有做笔记的可以会议之后做笔记了"); }private static class WorkThread extends Thread {private int WorkTime; private String WorkName; private CountDownLatch countDownLatch; public int getWorkTime() {return WorkTime; }public WorkThread(String WorkName, int WorkTime, CountDownLatch countDownLatch) {this.WorkName = WorkName; this.WorkTime = WorkTime; this.countDownLatch = countDownLatch; System.out.println(WorkName + " initialize time = " + WorkTime); }@Override public void run() {try {System.out.println(WorkName + " start work..."); WorkTime = WorkTime + 1; Thread.sleep(1000 * WorkTime); System.out.println(WorkName + " complete work step one WorkTime = " + WorkTime); //第一阶段 开会 完成后减一 countDownLatch.countDown(); //第二阶段 做笔记 Thread.sleep(5000); System.out.println(WorkName + " complete work step two WorkTime = " + WorkTime); } catch (InterruptedException e) {e.printStackTrace(); System.out.println(WorkName + " error work..."); }}} }
执行结果:
0 initialize time = 6
1 initialize time = 6
2 initialize time = 1
0 start work...
3 initialize time = 9
2 start work...
1 start work...
4 initialize time = 7
3 start work...
5 initialize time = 7
4 start work...
5 start work...
6 initialize time = 3
7 initialize time = 6
6 start work...
8 initialize time = 9
7 start work...
9 initialize time = 2
8 start work...
9 start work...
2 complete work step one WorkTime = 2
9 complete work step one WorkTime = 3
6 complete work step one WorkTime = 4
1 complete work step one WorkTime = 7
0 complete work step one WorkTime = 7
7 complete work step one WorkTime = 7
2 complete work step two WorkTime = 2
9 complete work step two WorkTime = 3
4 complete work step one WorkTime = 8
5 complete work step one WorkTime = 8
6 complete work step two WorkTime = 4
8 complete work step one WorkTime = 10
3 complete work step one WorkTime = 10
会议开始,大家没有做笔记的可以会议之后做笔记了
7 complete work step two WorkTime = 7
0 complete work step two WorkTime = 7
1 complete work step two WorkTime = 7
4 complete work step two WorkTime = 8
5 complete work step two WorkTime = 8
8 complete work step two WorkTime = 10
3 complete work step two WorkTime = 10
从结果可以看出有一部分是边开会边做笔记的,有一部分是会议结束之后做笔记的。这就是CountDownLatch独特的地方。
java多线程中CountDownLatch和join的使用相关推荐
- java多线程中的join方法详解
java多线程中的join方法详解 方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答. 自从接触Java多线程,一直对Join理解不了.JDK是这样说的:join p ...
- Java多线程中的ThreadLocal,可继承,可修改
Java多线程中的ThreadLocal,可继承,可修改. package test;import java.util.Date;public class InheritableThreadLocal ...
- java并发中CountDownLatch的使用
文章目录 主线程等待子线程全都结束之后再开始运行 等待所有线程都准备好再一起执行 停止CountdownLatch的await java并发中CountDownLatch的使用 在java并发中,控制 ...
- Java多线程中使用ReentrantLock、synchronized加锁 简单举例
Java多线程中使用ReentrantLock.synchronized加锁 简单举例 public class Demo {final static Lock lock = new Reentran ...
- java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?
转载自 java多线程中的死锁.活锁.饥饿.无锁都是什么鬼? 死锁.活锁.饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了. 死锁 死锁 ...
- java 多线程的单例模式,Java多线程中的单例模式两种实现方式
Java多线程中的单例模式 一.在多线程环境下创建单例 方式一: package com.ietree.multithread.sync; public class Singletion { priv ...
- java多线程同步与死锁_浅析Java多线程中的同步和死锁
Value Engineering 1基于Java的多线程 多线程是实现并发机制的一种有效手段,它允许编程语言在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间相互独立,且与进程一样拥有独立 ...
- 多线程中Thread的join方法
多线程中Thread的join方法 join简介 join方法是Thread类中的一个方法,该方法的定义是等待该线程执行直到终止.其实就说join方法将挂起调用线程的执行,直到被调用的对象完成它的执行 ...
- Java多线程中static变量的使用
Java中 没处理好同步 导致两个线程同时为一个static变量赋值 会导致什么后果? Java中 没处理好同步 导致两个线程同时为一个static变量赋值 会导致什么后果?仅仅是多耗资源还是会引发异 ...
最新文章
- 智能零售来了!Amazon Go无人商店周一正式对公众开放
- Linux驱动程序中THIS_MODULE 的定义
- 《Android开发从零开始》——22.数据存储(1)
- selenium-webdriver for node 鼠标滑动到指定元素
- 不是计算机专业及其相关专业,对软件编程一窍不通,能学好编程吗?
- 关于Netbeans调试PHP
- BZOJ1419: Red is good
- c语言求一个数的位数不用循环_LeetCode基础算法题第181篇:将数字减少为零的步骤数...
- vs2013 使用vs调试器,发现调试器显示的数据错误。查看内存,发现内存是正确的。...
- 凸优化第九章无约束优化 9.3 梯度下降方法
- SAP 软件PS 模块系统操作之一工作分解结构(WBS)的创建
- 神舟计算机主板bios,神舟HASEE笔记本电脑开机进入BIOS的方法与bios设置图解
- GIF动画录制工具(写教程时用的比较小巧的gif工具)
- 决策树分类算法三种方式
- CSS属性前的 -webkit, -moz
- Ubuntu环境下用docker从0到1部署Elasticsearch 7集群
- PHP5 session 详解【经典】
- jupyter远程访问服务器
- 仿开心网的前端页面 html+css
- String的inturn()的运用