kaka的gravatar头像
kaka 2018-03-20 11:22:03
java多线程类Thread的join方法

最近被问到如何让多线程按顺序执行,想到了join,但是不知道join内部具体的实现,翻看源码记录下。

先看个小例子,目标是让线程按照T3,T2,T1的顺序执行

public class T1 implements Runnable {
    private String threadName;
    public T1(String name){
        this.threadName = name;
    }
    public void run() {
        Thread t2 = new Thread(new T2("Thread2"));
        t2.start();
        try {
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("T1 is running:"+threadName);
    }
}
public class T2 implements Runnable{
    private String threadName;
    public T2(String name){
        this.threadName = name;
    }
    public void run() {
        Thread t3 = new Thread(new T3("Thread3"));
        t3.start();
        try {
            t3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("T2 is runing:"+threadName);
    }
}
public class T3 implements Runnable {
    private String threadName;
    public T3(String name){
        this.threadName = name;
    }
    public void run() {

        System.out.println("T3 is running:"+threadName);
    }
}

输出结果:T1调用T2的join后,T2子线程正常运行,T2调用T3的join后,T3子线程正常运行,T2等待T3运行结束后再运行,T1等待T2运行结束后再运行

java多线程类Thread的join方法

join作用:让主线程等待子线程执行完成后再执行,源码如下:

 public final void join() throws InterruptedException {
        join(0);
    }
public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }
 public final synchronized void join(long millis, int nanos)
    throws InterruptedException {

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        join(millis);
    }
public final native boolean isAlive();

最终实际调用的是 public final synchronized void join(long millis) throws InterruptedException 方法,下面看下这个方法:以mils参数为0来解释

主线程A中调用子线程B的join()方法,同时获取到了子线程B实例的锁(其他线程可以进入子线程B的join()方法,但是无法进入子线程B的join(0)方法),join(0)方法一直在调用native方法isAlive()检测子线程B的状态,如果子线程B是active的状态,调用子线程B的wait方法,此时主线程A释放了锁(wait方法会释放锁),其他线程可以竞争子线程B的实例锁。如果检测到子线程B的状态不是active,主线程A继续运行。


打赏

已有1人打赏

最代码官方的gravatar头像
最近浏览
gwl  LV8 2020年10月20日
月亮之城guo  LV8 2020年3月8日
shenguoxiao  LV1 2020年2月23日
loumeng  LV1 2019年12月4日
1248612588  LV1 2019年10月22日
2252536772  LV21 2019年9月10日
hohahei  LV4 2018年12月31日
景哥GG 2018年12月28日
暂无贡献等级
sinyuwl  LV3 2018年12月9日
851405506  LV7 2018年11月14日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友