3-等待线程终止的join方法

等待线程终止的join方法

  • 在项目实践中经常会遇到一个场景,就是需要等待某几件事完成之后才能继续往下执行,比如线程加载资源等等。

    package com.heiye.learn1;
    
    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!");
        }
    }
    

    image

  • 如上代码在主线程里面启动了两个线程,然后分别调用了它们的join方法,那么主线程首先会调用threadOne.join()执行完毕后返回,然后主线程调用threadTwo.join()方法后再次被阻塞,等待threadTwo执行完毕后返回。

  • 另外,线程A调用线程B的join方法会阻塞,当其他线程调用了线程A的Interrupt()方法中断了A时,线程A会抛出InterruptedException异常而返回。如下:

    package com.heiye.learn1;
    
    public class JoinTest2 {
        public static void main(String[] args) {
            Thread threadOne = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("threadOne begin run!");
                    for (; ; ) {
    
                    }
                }
            });
    
            //获取主线程
            final Thread mainThread = Thread.currentThread();
    
            //线程two
            Thread threadTwo = new Thread(new Runnable() {
                @Override
                public void run() {
                    //休眠1秒
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                    //中断主线程
                    mainThread.interrupt();
                }
            });
    
            //启动线程one
            threadOne.start();
            //延迟1s启动线程two
            threadTwo.start();
    
            try {//等待线程one结束
                threadOne.join();
            } catch (InterruptedException e) {
                //e.printStackTrace();
                System.out.println("main thread: " + e);
            }
        }
    }
    

    image

  • 如上代码在threadOne线程里陷入死循环,主线程调用threadOne.join()方法阻塞自己等待线程threadOne执行完毕,在threadTwo休眠1s后会调用主线程的inerrupt()方法设置主线程的中断标志,从结果上来看,主线程的threadOne.join()会抛出InterruptedException异常,这里另外注意的是,在threadTwo里面调用的是是主线程的interupt()方法,而不是线程threadOne的。

posted @ 2021-09-23 12:25  LilyFlower  阅读(78)  评论(0编辑  收藏  举报