常见多线程面试题之Thread的join()方法
来源:互联网 发布:centos nginx默认目录 编辑:程序博客网 时间:2024/05/29 19:21
join简介
join方法是Thread类中的一个方法,该方法的定义是等待该线程终止。其实就是join()方法将挂起调用线程的执行,直到被调用的对象完成它的执行。这段话难理解,后面我会用实例做讲解。
join实例
现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?这个问题是网上很热门的面试题目(这里除了用join之外还有很多其他方法能够实现,只是使用join是最简单的方案),下面是实现的代码:
/** * 现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行? * @author RJH * 2017年11月24日 */public class JoinDemo { public static void main(String[] args) { //初始化线程t1,由于后续有匿名内部类调用这个对象,需要用final修饰 final Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("t1 is running"); } }); //初始化线程t2,由于后续有匿名内部类调用这个对象,需要用final修饰 final Thread t2 = new Thread(new Runnable() { @Override public void run() { try { //t1调用join方法,t2会等待t1运行完之后才会开始执行后续代码 t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("t2 is running"); } } }); //初始化线程t3 Thread t3 = new Thread(new Runnable() { @Override public void run() { try { //t2调用join方法,t3会等待t2运行完之后才会开始执行后续代码 t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } finally { System.out.println("t3 is running"); } } }); //依次启动3个线程 t1.start(); t2.start(); t3.start(); }}
输出结果:
t1 is runningt2 is runningt3 is running
结果分析:
在t2线程中t2本身就是调用线程,所谓的调用线程是指调用了t.join()方法的线程,而被调用的对象指的是调用join方法的线程对象,即t1。所以这3个线程按照t1->t2->t3的顺序执行了。
join方法源码分析
/** *等待该线程终止的时间最长为 millis 毫秒。超时为 0 意味着要一直等下去。 *millis - 以毫秒为单位的等待时间。 */public final synchronized void join(long millis) throws InterruptedException { //获取启动时的时间戳,用于计算当前时间 long base = System.currentTimeMillis(); //当前时间 long now = 0; if (millis < 0) {//等待时间不能小于0则抛出IllegalArgumentException throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) {//等待时间为0,则无限等待 //需要注意,如果当前线程未被启动或者终止,则isAlive方法返回false //即意味着join方法不会生效 while (isAlive()) { wait(0); } } else { //需要注意,如果当前线程未被启动或者终止,则isAlive方法返回false //即意味着join方法不会生效 while (isAlive()) { //计算剩余的等待时间 long delay = millis - now; if (delay <= 0) {//如果剩余的等待时间小于等于0,则终止等待 break; } //等待指定时间 wait(delay); //获取当前时间 now = System.currentTimeMillis() - base; } }}
从源码中可以得知,如果要join正常生效,调用join方法的对象必须已经调用了start()方法且并未进入终止状态。
阅读全文
0 0
- 常见多线程面试题之Thread的join()方法
- 多线程常见的面试题
- 多线程:Thread类的Join()方法
- 多线程:Thread类的Join()方法
- 多线程_多线程常见的面试题
- 多线程-多线程常见的面试题
- 多线程常见面试题
- 多线程常见面试题
- Thread之join()方法
- java多线程-join方法详解(附面试题)
- Thread(多线程基础面试题)
- Java多线程 之 Thread子类 join方法(五)
- Java多线程(一)——Thread之join()方法
- Thread的join()方法
- Thread的join()方法
- Thread的join方法
- Java的多线程:Thread类的Join()方法
- Java多线程学习 (二) Thread的join()方法
- Spring框架
- Jdk自带的动态代理技术
- nyoj306 走迷宫(二分+dfs)
- 树的重心(默认已会定义及存储)
- IO流(二)————字符流
- 常见多线程面试题之Thread的join()方法
- 零基础IDEA中搭建springboot工程项目
- JDK开发环境配置
- linux目录
- 共享内存
- 开2个坑,也算是督促自己学习
- 2N7002这个场效应管做开关
- opencv for pyhthon (4) 把鼠标当画笔
- leetcode125-Valid Palindrome