java join为什么会阻塞主线程?

join使用

上篇我们介绍了CountDownLatch,顺便说到了Thread中的join方法!

import java.util.concurrent.TimeUnit;

/**

 * @author :jiaolian

 * @date :Created in 2021-02-28 21:43

 * @description:join测试

 * @modified By:

 * 公众号:叫练

 */

public class JoinTest {

    public static void main(String[] args) throws InterruptedException {

        Thread threadA = new Thread(()->{

            try {

                TimeUnit.SECONDS.sleep(2);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName()+":想先执行");

        },"线程A");

        //开启一个线程A

        threadA.start();

        //主线程会持有子线程的锁,子线程还没开始主线程就阻塞了,等待子线程结束后通知;

        threadA.join();

        System.out.println(Thread.currentThread().getName()+ "线程执行");

    }

}

如上代码所示:在JoinTest开启一个线程A,threadA调用join()方法,主线程会等待threadA执行完毕!也就是两秒后,主线程执行最后一句话,运行结果如下图所示!

join为啥会阻塞主线程?

我们深入源码,join方法底层其实就是一个wait方法,但现在问题是:明明调用者是线程A,可阻塞的是mian线程,不应该阻塞的是threadA吗?

 

证明问题:明明调用者是线程A,可阻塞的是mian线程

我们参照Thread中join源码,将上面的代码改造如下:

import java.util.concurrent.TimeUnit;

/**

 * @author :jiaolian

 * @date :Created in 2021-02-28 21:43

 * @description:join测试

 * @modified By:

 * 公众号:叫练

 */

public class JoinCodeTest {

    public static void main(String[] args) throws InterruptedException {

        MyThread threadA = new MyThread("线程A");

        //开启一个线程A

        threadA.start();

        //主线程会持有子线程的锁,子线程还没开始主线程就阻塞了,等待子线程结束后通知;

        threadA.join2(0);

        System.out.println(Thread.currentThread().getName()+ "线程执行");

    }

    private static class MyThread extends Thread {

        public MyThread(String name) {

            super(name);

        }

        @Override

        public void run() {

            try {

                TimeUnit.SECONDS.sleep(2);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName()+":想先执行");

        }

        //复制Thread源码中的join方法测试阻塞的是线程A还是main线程?

        public final synchronized void join2(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()) {

                    //虽然调用者是线程A,但真正执行阻塞的是main线程!

                    System.out.println(Thread.currentThread().getName()+"会阻塞");

                    wait(0);

                }

            } else {

                while (isAlive()) {

                    long delay = millis - now;

                    if (delay <= 0) {

                        break;

                    }

                    wait(delay);

                    now = System.currentTimeMillis() - base;

                }

            }

        }

    }

}

如上代码所示:MyThread继承Thread,并复制了join源码,将join修改成join2,并在join2方法中增加了一个输出语句,System.out.println(Thread.currentThread().getName()+"会阻塞")用来测试阻塞的是线程A还是main线程,所以在JoinCodeTest的main方法中ThreadA是调用join2方法,

结果发现进入join2方法的线程是main线程。运行结果如下图所示!

join为啥会阻塞主线程?

这里可以把join理解成一个普通方法!真正阻塞的不是调用者线程,而是当前正在执行的线程。

总结

今天我们介绍了join方法,特别是将源码中代码copy出来证明测试,相信整理出来希望能对你有帮助,写的比不全,同时还有许多需要修正的地方,希望亲们加以指正和点评

以上是 java join为什么会阻塞主线程? 的全部内容, 来源链接: utcz.com/a/117984.html

回到顶部