天天看點

Java Thread.join(),結合例子隻學一次

我們直接結合代碼來講解,

建立一個SimpleTestDemo.java,在裡面分别調用三個子線程(三種編寫方式,其實都一樣):

public class SimpleTestDemo {


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

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

                try {
                    System.out.println("1111111111111  Thread");
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });
        //運作子線程 1
        t1.start();


        Thread t2=new Thread(() -> {

            try {
                System.out.println("2222222222222  Thread");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        //運作子線程 2
        t2.start();


        Thread t3= new Thread(() -> System.out.println("3333333333333  Thread"));
        //運作子線程 3
        t3.start();


        //主線程的輸出
        System.out.println("  The End  !");

    }
}      

運作結果:

Java Thread.join(),結合例子隻學一次
Java Thread.join(),結合例子隻學一次

從運作結果,可以看到,三個子線程異步執行,是以導緻每次運作的輸出結果不一定是一樣的,因為都在搶資源。

為了讓這種異步執行的場景模拟更加真實,我們在子線程1上加上sleep(2000):

Java Thread.join(),結合例子隻學一次

再看看運作結果,因為子線程1執行時間久,是以最後才執行完畢:

Java Thread.join(),結合例子隻學一次

OK,接下來就是Thread.join()的運用了。  

雖然子線程1執行得久,但是我們依然想先確定子線程1被執行完畢後才執行後面的代碼,那麼我們就需要調用子線程1的join()方法:

Java Thread.join(),結合例子隻學一次

這樣我們再看看運作結果,盡管子線程1執行了很久,但是其他的代碼依然等待子線程1執行完畢再進行執行:

Java Thread.join(),結合例子隻學一次

到這裡,很明顯已經看到了join的作用了,簡單來說,就是主線程跟各子線程之間其實都是異步的執行的;

但是如果使用了某個子線程的join()方法,那麼就是 強行在此刻轉變成了同步執行,也就是後面還未執行的代碼(子線程調用等),都必須等,等到使用join()方法的線程執行完畢才能繼續放飛自我。

 那麼join方法還有其他作用麼, 有的,在調用的時候發現是可以填入參數的:

Java Thread.join(),結合例子隻學一次

這個參數,毫秒,作用是什麼呢?

作用是最大等待時間,也就是說雖然使用了join(),後面的代碼需要等待這個子線程執行完畢後才能開始運作,但是我們如果想實作,如果這子線程執行時間超過某個限制,我們就不等了,直接執行後面的代碼,這麼我們隻需要把限制時間毫秒級别作為參數填入join()即可。

之前我們子線程1 sleep(2000),那麼我們就嘗試下join(1000),也就是說,超過1000毫秒,就不等了:

Java Thread.join(),結合例子隻學一次

看看運作結果,雖然子線程1使用了join,但是我們加上了最大等待時間1000毫秒,是以等了1000毫秒後,後面的代碼直接運作了,最後最後子線程1才執行完畢輸出了内容: