java thread join

java多線程編程join的作用是等待線程結束,這個作用可以產生很多特定的場景。
1)A線程中調用B線程的join方法,那麼A線程需要等待B線程執行完成後才能完成
2)主線程中依次調用A線程的join方法,B線程的join方法,可以保證A,B線程順序執行;當主線程需要等待多個線程完成後再繼續執行時,join方法可能會產生迷惑作用,雖然這個時候主線程等到了多個線程的完成,但是這時多個線程的執行並不是併發執行的,要解決這個問題,可以採用CountdownLatch來完成,CountdownLatch是線程流程控制方式的一種,另外一種是CycliBarrier,它具有等待多個線程完成時,執行一個線程的功能,這樣也可以滿足等待的需求。

下面是一個使用join的錯誤情況:

public class NoSafe {
    public static void main(String argv[]) {
        final List<String> list = new ArrayList<String>();
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread("Thread"+i) {
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " Start!");
                    for (int i = 0; i < 100; i++) {
                        list.add(String.valueOf(i));
                    }
                }
            };
            t.start();
            try {
                t.join();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println(list.size());
    }
}

上面例子中實際上多個線程是順序執行的,並沒有併發執行,因此對ArrayList的使用沒有拋出任何的異常,當我們去掉join之後再次執行,情況就不一樣了,這個時候會產生意想不到的異常,比如ArrayIndexOutOfBoundsException等,我們可以嘗試將ArrayList換成LinkedList來查看執行結果,這個時不會產生異常,但是數據量不對,最終的size不是1000。試着將list換成CopyOnWriteArrayList然後再來運行看看結果。這個時候沒有異常,數據量也是正確的。
當然了,爲了等待最終的結果,我們必須想辦法讓主線程等待所有線程執行結束,這裏爲了測試的話,可以在輸出結果之前在主線程中添加Sleep達到這個目的,當然最好的實現還是使用流程控制的方法,比如CountDownLatch或者CycliBarrier。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章