Java并发编程(四)等待线程执行终止的join方法

逆流者 2021年02月21日 64次浏览

在项目实践中经常会遇到一个场景,就是需要等待某几件事情完成后才能继续往下执行,比如多个线程加载资源,需要等待多个线程全部加载完毕再汇总处理。Thread类中有一个join方法就可以做这个事情,join方法则是Thread类直接提供的。join是无参且返回值为void的方法。

正常示例

public class JoinTest {

    public static void main(String[] args) throws InterruptedException {
        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("child threadOne over!");
            }
        });

        Thread threadTwo = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("child threadTwo over!");
            }
        });

        threadOne.start();
        threadTwo.start();

        System.out.println("wait all child thread over!");

        // 等待子线程执行完,返回
        threadOne.join();
        threadTwo.join();

        System.out.println("all child thread over!");

    }
}
wait all child thread over!
child threadOne over!
child threadTwo over!
all child thread over!

根据程序执行结果, 主线程的两条打印语句在子线程的前后, 说明在主线程中执行threadOne.join()语句, 当前主线程会阻塞, 等待子线程执行完, 接着往下执行.

join 中断示例

阻塞的线程, 如果被其他线程执行了interrupt() 方法会报InterruptedException 异常

public class JoinInterruptedExceptionTest {

    public static void main(String[] args) {

        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {

                System.out.println("child threadOne begin run!");
                // threadOne 放一个死循环
                for (;;) {
                }
            }
        });


        // 获取主线程
        final Thread mainThread = Thread.currentThread();

        Thread threadTwo = new Thread(new Runnable() {
            @Override
            public void run() {

                // threadTwo 上来就休眠1s
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 中断主线程
                mainThread.interrupt();
            }
        });

        threadOne.start();
        threadTwo.start();

        try {
            threadOne.join();
        } catch (InterruptedException e) {
            System.out.println("main thread:" + e);
        }

    }
}
child threadOne begin run!
main thread:java.lang.InterruptedException

执行结果: 主线程被中断了, 主线程一直在等待threadOne 执行结束, 但threadOne是死循环, 当threadTwo 中断main线程时就会报中断异常.