线程join方法详解
执行逻辑:在当前代码块(比如main方法)中的线程A执行了join方法,
那么当代码块(main)执行到join方法时,会停止继续向下执行,一直到线程A执行完毕,
main方法才会继续向下执行。
代码一:
package com.thread; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream; public class ThreadJoin {
public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
},"线程1");
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
},"线程2"); //启动线程1
thread1.start();
//启动线程2
thread2.start(); /**
* 当代码执行到这一步的时候,程序不再向下执行,等待thread1执行完毕后向下执行
* 同时thread1和thread2相互挣多cpu调度资源
*/
thread1.join();
/**
* 当代码执行到这一步的时候,程序不在向下执行,等待thread2执行完毕后向下执行
* 因为此时的thread1已经执行完毕了,只用thread2执行
*/
thread2.join(); for(int i=0;i<2;i++){
System.out.println(Thread.currentThread().getName()+"#"+i);
TimeUnit.SECONDS.sleep(1);
}
} }
使用案例:
假如现在有一个长途车票销售网站,想要查询合肥到上海的汽车;
而合肥又有很多的汽车站(合肥1站,合肥2站,合肥3站),同时上海也有很多的汽车站(上海1站,上海2站,上海3站)。
这个时候网站平台需要调用合肥的各个汽车平台官方的接口来获取合肥到上海的车票信息。
正常的同步思维应该是这样子的:
1.先调用合肥1站到上海站的车票信息,耗时3s,
2.调用合肥2站到上海站的车票信息,耗时5s,
3.调用合肥3站到上海站的车票信息,耗时1s。
等这3个接口调用完毕后,组装返回的参数展示到界面。
有了线程的join方法就可以同时让这三个接口去请求接口,等三个接口调用完毕后再组装参数展示给客户。
这是总耗时取决于返回接口数据最慢的那一个接口。
Platform.java 车站类
package com.thread.car; import java.util.ArrayList;
import java.util.List; /**
* 合肥车站1
*/
public class PlatForm { private String startCity;
private String endCity; public PlatForm(String startCity,String endCity) {
this.startCity=startCity;
this.endCity=endCity;
} private final List<String> list=new ArrayList<>(); public void search(){
this.list.add(this.startCity+"站到"+this.endCity+"1站的信息");
this.list.add(this.startCity+"站到"+this.endCity+"2站的信息");
this.list.add(this.startCity+"站到"+this.endCity+"3站的信息");
}
public List<String> get(){
return this.list;
}
}
Test.java 测试类
package com.thread.car; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit; public class Test { /*private static List<String> resList=new ArrayList<>();
private static synchronized void addList(List<String> list){
resList.addAll(list);
}*/ public static void main(String[] args) throws InterruptedException {
//List<String> list=new ArrayList<String>();
PlatForm pf1=new PlatForm("合肥1","上海");
PlatForm pf2=new PlatForm("合肥2","上海");
PlatForm pf3=new PlatForm("合肥3","上海"); Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
try {
pf1.search();
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName()+"执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"合肥1站");
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
try {
pf2.search();
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"合肥2站");
Thread thread3=new Thread(new Runnable() {
@Override
public void run() {
try {
pf3.search();
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName()+"执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"合肥3站"); thread1.start();
thread2.start();
thread3.start(); long start=System.currentTimeMillis();
thread1.join();
thread2.join();
thread3.join();
long end=System.currentTimeMillis();
System.out.println((end-start)/1000);
List<String> list=new ArrayList<String>();
list.addAll(pf1.get());
list.addAll(pf2.get());
list.addAll(pf3.get());
for(String s:list){
System.out.println(s);
} }
}
线程join方法详解的更多相关文章
- [java] java 线程join方法详解
join方法的作用是使所属线程对象正常执行run方法,而对当前线程无限期阻塞,直到所属线程销毁后再执行当前线程的逻辑. 一.先看普通的无join方法NoJoin.java public class N ...
- “全栈2019”Java多线程第七章:等待线程死亡join()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第六章:中断线程interrupt()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第十二章:后台线程setDaemon()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java并发编程--多线程中的join方法详解
Java Thread中, join()方法主要是让调用该方法的thread在完成run方法里面的部分后, 再执行join()方法后面的代码 例如:定义一个People类,run方法是输出姓名年龄. ...
- JAVA THREAD.JOIN方法详解
一.使用方式. join是Thread类的一个方法,启动线程后直接调用,例如: Thread t = new AThread(); t.start(); t.join(); 二.为什么要用join() ...
- Java多线程中join方法详解
join()方法用于让当前执行线程等待join线程执行结束.其实现原理是不停的检查join线程是否存活,如果join线程存活则让当前线程永远等待. join()方法部分实现细节 while(isAli ...
- join() 方法详解及应用场景
总结:join方法的功能就是使异步执行的线程变成同步执行.也就是说,当调用线程实例的start方法后,这个方法会立即返回,如果在调用start方法后后需要使用一个由这个线程计算得到的值,就必须使用jo ...
- java线程基础方法详解
一.线程状态转换 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行 ...
随机推荐
- Python异常处理与上下文管理器
Python异常处理 异常与错误 错误 可以通过IDE或者解释器给出提示的错误opentxt('a.jpg','r') 语法层面没有问题,但是自己代码的逻辑有问题if age>18: print ...
- Python-TCP客户端程序开发
TCP客户端,需要与服务端建立连接,连接建立成功后才可以进行数据的传输. # 1.导入模块 import socket if __name__ == '__main__': # 2.创建套接字对象 t ...
- 简单易懂的ftp脚本自动登录教程
我在上上篇<nmon脚本--对Linux服务器的监控>的脚本中,使用了ftp的自动登录.结果有人询问,遂决定专门写一篇简单易懂的博客,来说明如何解决ftp的自动登录问题. 一.Window ...
- Mybatis底层源码分析
MyBatis 流程图 Configuration.xml 该配置文件是 MyBatis 的全局配置文件,在这个文件中可以配置诸多项目.常用的内容是别名设置,拦截器设置等. Properties(属性 ...
- kettle教程---kettle作业调度,附件(excel)配置表名,一个调度完成所有的表操作
在平时工作当中,会遇到这种情况:复制一个库,几百甚至上千张表,并且无法设置dblink,此时通过kettle可以快速完成该任务. 按照正常的调度,有几百张表,咱们就要写几百个转换去处理,很不科学,下面 ...
- 从零开始openGL——三、模型加载及鼠标交互实现
前言 在上篇文章中,介绍了基本图形的绘制.这篇博客中将介绍模型的加载.绘制以及鼠标交互的实现. 模型加载 模型存储 要实现模型的读取.绘制,我们首先需要知道模型是如何存储在文件中的. 通常模型是由网格 ...
- Mac ifconfig 详解(ifconfig detail)-- 外婆送来的丁香(Grandma's clove)
引言 Intro 图片源链:https://pixnio.com/zh/%E6%A4%8D%E7%89%A9/%E8%8A%B1/%E4%B8%81%E9%A6%99%E8%8A%B1-%E5%8F% ...
- java的传参究竟是按值传递的还是按引用传递的
这里来弄清楚Java的传参究竟是按值传递的还是按引用传递的. 形参和实参 传参的概念里,有形参和实参的区分.形参是定义方法名和方法体的时候使用的参数,目的是用来接收调用该方法的时候传入的参数:实参是调 ...
- Vue ---- 项目与环境搭建 初始项目结构 Vue生命周期
目录 1. vue环境搭建 2. Vue项目搭建 pycharm配置并启动vue项目 3 . 认识项目 1. vue项目目录结构 2. 配置文件:vue.config.js 3. main.js 4. ...
- 更新Preloader和uboot
在SoCEDS环境下编译和更新preloader和uboot程序的方法 前面有介绍preloader在HPS boot过程中的的作用,接下来讲述下用户在SoCEDS环境下改如何编译preloade ...