Thread的join方法-实现线程顺序打印

251 阅读2分钟

Thread.join()方法介绍

join()是Thread的一个方法,是等待该线程终止。将调用线程挂起,等待其执行完成。
当调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行。

Thread.join()使用场景

  1. 线程A\B\C 顺序执行
  2. 主线程创建子线程,子线程执行时间长大于主线程执行时间。如果主线程需要知道子线程结束的结果时,join()是个比较好的场景

Thread.join 提供3个重载的方法

  • 3个都是final修饰符,无法被修改
  • join()等价于join(0)
  • join(大于0)表示会等待一段时间
 public final void join() throws InterruptedException;

 public final synchronized void join(long millis) throws InterruptedException;
 
 public final synchronized void join(long millis, int nanos) throws InterruptedException;
 
 

Thread.join()源码分析

/**
 * Waits for this thread to die.  等待此线程结束
 */
public final void join() throws InterruptedException {
    join(0);
}


public final synchronized void join(long millis) throws InterruptedException {
    //获取当前时间
    long base = System.currentTimeMillis();
    long now = 0;

    //等待时间小于0会抛出异常IllegalArgumentException
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    //不加参数的调用,默认时间为0,会无线等待下去
    if (millis == 0) {
        //isAlive本地方法,线程未启动或结束会返回false
        while (isAlive()) {
            wait(0);
        }
    } else {
        //添加参数调用
        while (isAlive()) {
            //算出还需要等待的时间
            long delay = millis - now;
            //如果等待时间小于等于0,则退出等待
            if (delay <= 0) {
                break;
            }
            //继续等待
            wait(delay);
            
            now = System.currentTimeMillis() - base;
        }
    }
}

Thread.join() 让线程A 线程B 线程C 顺序执行

package lock;

import java.util.Random;

/**
 * @Author: javanull on 2021/9/7.
 */
public class JoinDemo {
    public static void main(String[] args) {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("threadA运行");
            }
        });


        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
//threadB调用threadA的join方法,threadB会等待threadA运行完之后才会开始执行后续代码
                try {
                    threadA.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("threadB运行");
            }
        });

        Thread threadC = new Thread(new Runnable() {
            @Override
            public void run() {
//threadC调用threadB的join方法,threadC会等threadB运行完之后才会开始执行后续代码
                try {
                    threadB.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("threadC运行");
            }
        });

        threadA.start();
        threadB.start();
        threadC.start();
    }
}

结果

threadA运行
threadB运行
threadC运行