java中的Thread#join实现原理分析

Java artisan 278℃ 0评论

join方法是来至于Thread类,不同于wait,notify方法;当多个线程需要等待某一个线程执行结束继续执行时,就需要使用join方法,

示例1:

public class ThreadJoin {

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t1 thread task done!");
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t2 thread task done!");
            }
        });

        t1.start();
        t2.start();
        System.out.println("all task exec done.");
    }
}

//输出
// all task exec done.
// t1 thread task done!
// t2 thread task done!

跟预期的不符。

示例2:

public class ThreadJoin {

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t1 thread task done!");
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t2 thread task done!");
            }
        });

        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            //因为wait方法需要抛出InterruptedException异常
            e.printStackTrace();
        }

        System.out.println("all task exec done.");
    }
}

// 按照预期输出
// t1 thread task done!
// t2 thread task done!
// all task exec done.

Thread#join方法分析


/** * Waits at most {@code millis} milliseconds for this thread to * die. A timeout of {@code 0} means to wait forever. * * <p> 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. * * @param millis the time to wait in milliseconds * @throws IllegalArgumentException if the value of {@code millis} is negative * @throws InterruptedException if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ 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释放监视器 wait(0); } } else { // 同理如上 while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } //MENO: 到此完成join执行,可能存在困惑notifyAll是在哪里调用的?翻遍Thread源码未见有notifyAll调用。 //MENO: notifyAll调用实则是在JVM终止线程是否调用的,是C代码调用的,参见openJDK源码的Thread.cpp文件 }

转载请注明:Java工匠师 » java中的Thread#join实现原理分析

喜欢 (3)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址