JavaThread方法总结-join方法

等待被调用线程运行结束。

main线程调用了JoinedThread线程的join方法,则main线程会等到JoinedThread线程运行结束再继续执行。

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        JoinedThread joinedThread = new JoinedThread(); //新建任务线程
        int start = LocalDateTime.now().getSecond();    //开始时间
        joinedThread.start();    //调用任务线程
        joinedThread.join();     //等待任务线程结束
        int end = LocalDateTime.now().getSecond();      //终了时间
        System.out.println("从开始到join结束用了"+ (end-start) + "秒");   //5s
    }
}
class JoinedThread extends Thread{
    public void run(){
        try {
            Thread.currentThread().sleep(5000);  //任务线程执行5秒后结束
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

上图所示,JoinedThread运行需要5秒,则main线程调用了joinedThread的join方法之后,要等到5秒之后才能继续执行。有点类似于特殊条件的CountDownLatch。

我们看join的源码

/**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *//
 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); //delay是剩余等待时间
                now = System.currentTimeMillis() - base;
            }
        }
    }

有一个参数millis,表示main线程只在millis毫秒内等待JoinedThread线程执行结束,若时间到了,即使JoinedThread线程没有运行结束,也不再继续等待。但若millis为0,则一直等待。我们可以看到,主要实现是使用 isAlive()作为判定条件的wait()循环。

wait方法上的注释原话,一直等待,直到其他线程完成特定动作之后,调用notify或者notifyAll方法通知处于wait状态的线程。而join方法可以理解为一直等待线程死亡。而这个线程死亡,不也是特定动作的一种吗,所以join其实就是特殊的wait而已。还是用最上面的例子来说。当JoinedThread线程死亡的时候,JoinedThread的isAlive标志位会被设定为false,虚拟机会自己调用JoinedThread的notify()方法,这样循环再次启动,判定false并退出循环,等待结束。

我们可以发现,若main线程调用自己的join方法的话,相当于自己等待自己死亡,程序永远也不会结束。

经验分享 程序员 微信小程序 职场和发展