官术网_书友最值得收藏!

1.4 等待線程執(zhí)行終止的join方法

在項(xiàng)目實(shí)踐中經(jīng)常會(huì)遇到一個(gè)場(chǎng)景,就是需要等待某幾件事情完成后才能繼續(xù)往下執(zhí)行,比如多個(gè)線程加載資源,需要等待多個(gè)線程全部加載完畢再匯總處理。Thread類中有一個(gè)join方法就可以做這個(gè)事情,前面介紹的等待通知方法是Object類中的方法,而join方法則是Thread類直接提供的。join是無(wú)參且返回值為void的方法。下面來(lái)看一個(gè)簡(jiǎn)單的例子。

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! ");
            }
        });
        //啟動(dòng)子線程
        threadOne.start();
        threadTwo.start();
        System.out.println("wait all child thread over! ");
        //等待子線程執(zhí)行完畢,返回
        threadOne.join();
        threadTwo.join();
        System.out.println("all child thread over! ");
    }

如上代碼在主線程里面啟動(dòng)了兩個(gè)子線程,然后分別調(diào)用了它們的join()方法,那么主線程首先會(huì)在調(diào)用threadOne.join()方法后被阻塞,等待threadOne執(zhí)行完畢后返回。threadOne執(zhí)行完畢后threadOne.join()就會(huì)返回,然后主線程調(diào)用threadTwo.join()方法后再次被阻塞,等待threadTwo執(zhí)行完畢后返回。這里只是為了演示join方法的作用,在這種情況下使用后面會(huì)講到的CountDownLatch是個(gè)不錯(cuò)的選擇。

另外,線程A調(diào)用線程B的join方法后會(huì)被阻塞,當(dāng)其他線程調(diào)用了線程A的interrupt()方法中斷了線程A時(shí),線程A會(huì)拋出InterruptedException異常而返回。下面通過(guò)一個(gè)例子來(lái)加深理解。

    public static void main(String[] args) throws InterruptedException {
        //線程one
        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() {
                //休眠1s
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //中斷主線程
                mainThread.interrupt();
            }
        });
        // 啟動(dòng)子線程
        threadOne.start();
        //延遲1s啟動(dòng)線程
        threadTwo.start();
        try{//等待線程one執(zhí)行結(jié)束
            threadOne.join();
        }catch(InterruptedException e){
            System.out.println("main thread:" + e);
        }
    }

輸出結(jié)果如下。

如上代碼在threadOne線程里面執(zhí)行死循環(huán),主線程調(diào)用threadOne的join方法阻塞自己等待線程threadOne執(zhí)行完畢,待threadTwo休眠1s后會(huì)調(diào)用主線程的interrupt()方法設(shè)置主線程的中斷標(biāo)志,從結(jié)果看在主線程中的threadOne.join()處會(huì)拋出InterruptedException異常。這里需要注意的是,在threadTwo里面調(diào)用的是主線程的interrupt()方法,而不是線程threadOne的。

主站蜘蛛池模板: 且末县| 鄂托克前旗| 贺兰县| 阜阳市| 大安市| 涪陵区| 南康市| 平顺县| 黑山县| 桃园市| 海丰县| 合川市| 郸城县| 固安县| 五家渠市| 左贡县| 郎溪县| 越西县| 岗巴县| 界首市| 潍坊市| 汪清县| 大兴区| 雅安市| 公主岭市| 十堰市| 北京市| 丹凤县| 扶沟县| 昌宁县| 黔江区| 唐海县| 云阳县| 宁河县| 运城市| 莲花县| 汉阴县| 永善县| 池州市| 平远县| 尚义县|