百度了一下,終於明白了。這個解釋最簡單:
前提:join()方法肯定是被某個線程調用的。
A線程正在執行,突然執行的時候碰到了B.join(), 那么,A線程就必須要等到B線程執行完之后才能執行。
注意理解,是在A線程運行中,遇到了B.join().
MyTthread d = new MyThread();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t1.join();
t2.start();
這個是main線程運行的時候碰到了t1.join, 那么主線程就必須要等到t1線程執行完了之后,才能繼續執行主線程。
至於,t1與t2線程,二者還是競爭關系。這個可以通過代碼簡單去驗證:

package thread; public class ThreadTest{ public static void main(String[] args) throws InterruptedException { MyThread d1 = new MyThread("t1",2000); MyThread d2 = new MyThread("t2", 2000); Thread t1 = new Thread(d1); Thread t2 = new Thread(d2); t1.start(); t2.start(); t1.join(); for(int i = 0; i < 50; i++){ System.out.println("Main:-->" + i); } } } class MyThread extends Thread{ private String threadName; private int times; public MyThread(String threadName, int times){ this.threadName = threadName; this.times = times; } public void run(){ for(int i = 0 ; i < times; i++){ System.out.println(threadName + ":-->" + i); } } }
這個的結果,main線程執行到t1.start(), t1線程啟動后繼續執行,當main線程執行到t1.join()時,main線程開始等待t1執行完成,完成之后,main線程繼續執行,執行到t2.start()時,t2線程才開始啟動。
如果10-12行換一下順序:
t1.start();
t2.start();
t1.join();
那么,應該是t1線程和t2線程交叉執行,當執行到t1.join()時,main線程等待t1執行完成,但是t1和t2依然是競爭關系,等t1執行完成之后,main線程會開始執行,如果t2這個時候還沒有完成,則t2又會和main線程交叉執行。
這個測試呢,只需要在MyThread d1 = new MyThread("t1",2000);時,通過控制t1和t2線程的打印此時來控制存活時間就可以了。比如t1與t2都比較大,那么看看最后一段是不是t1和t2交叉執行的,或者t1在t2后執行的,這樣就能說明t1.join()對於t2是沒有任何影響的。
一般,如果t1線程有一些耗費時間的處理,那么t1.join()就會保證等t1執行完成之前,main線程還存活者,main就相當於一個守護線程。 可能t1的處理結果正是main線程處理時需要的。
有些人理解成,將兩個線程合並成一個,也很好理解。這里將t1與主線程合並成一個線程,t1繼續與t2競爭執行。t1線程則是順序執行的。t1部分完成之后,main部分開始執行。
也可以這么理解,t1.join相對於main來說,加一一把鎖,控制了t1與main線程之間的同步。