Java多線程學習——join方法的使用


join在線程里面意味着“插隊”,哪個線程調用join代表哪個線程插隊先執行——但是插誰的隊是有講究了,不是說你可以插到隊頭去做第一個吃螃蟹的人,而是插到在當前運行線程的前面,比如系統目前運行線程A,在線程A里面調用了線程B.join方法,則接下來線程B會搶先在線程A面前執行,等到線程B全部執行完后才繼續執行線程A。

而在JDK的解釋中,join方法被解釋成等待這個線程死亡,也就是等待這個線程全部執行完后才繼續執行接下來的進程。

public class Test1 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread1=new Thread(new Test1(),"線程一");
        Thread thread2=new Thread(new Test1(),"線程二");
        Thread thread3=new Thread(new Test1(),"線程三");
        thread1.start();
        thread2.start();
        thread3.start();

        System.out.println("------------------主線程到此-------------------");
        /*thread2.join(); */

        for (int i = 0; i < 20; i++) {
            System.out.println("主線程"+i);
        }
    }

}

在上面這個例子中,在主線程里面開啟了3個子線程,結果是主線程先執行完再執行其他線程。

加上讓線程2先執行完再執行主線程join后

public class Test1 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread1=new Thread(new Test1(),"線程一");
        Thread thread2=new Thread(new Test1(),"線程二");
        Thread thread3=new Thread(new Test1(),"線程三");
        thread1.start();
        thread2.start();
        thread3.start();

        System.out.println("------------------主線程到此-------------------");
        thread2.join(); //讓線程2先執行完主線程才能繼續執行

        for (int i = 0; i < 20; i++) {
            System.out.println("主線程"+i);
        }
    }

}

結果是

 

/**
 * join的用法,哪個線程調用join哪個線程就插隊先執行
 */

public class Test{

    public static void main(String[] args) throws InterruptedException {
        //開啟Father線程,滿足Father需求
        new Thread(new Father()).start();
    }

}

class Father implements Runnable{

    @Override
    public void run() {
        System.out.println("老爸要抽煙,發現沒煙了,給了100塊讓兒子去買中華......");
        Thread son=new Thread(new Son());   //讓兒子去買煙
        son.start();    //開啟兒子線程后,兒子線程進入就緒狀態等待CPU調度,不一定立即執行兒子線程,所以可能會出現兒子沒把煙買回來老爸就有煙抽了
/*        try {
            son.join(); //讓兒子先插隊去買煙
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("兒子不見了,報警尋找");
        }*/
        System.out.println("老爸接過煙,把零錢給了兒子");
        System.out.println("兒子很開心,出門去了游戲廳");
    }
}

class Son implements Runnable{

    @Override
    public void run() {
        System.out.println("兒子接過錢蹦躂出了門");
        System.out.println("路過游戲廳玩了10秒鍾");
        for (int i = 1; i <= 10; i++) {
            System.out.println(i+"秒");
            try {
                Thread.sleep(1000); //此時休眠可能會讓其他線程進行,出錯率增加,通過join方法解決
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("趕緊去買煙");
        System.out.println("回家把煙給老爸");
    }
}

 

 加入了join方法后,運行結果正確

try {
            son.join(); //讓兒子先插隊去買煙
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("兒子不見了,報警尋找");
        }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM