敏捷是一條很長的路,摸索著前進著
一、在研究join的用法之前,先明確兩件事情。
1.join方法定義在Thread類中,則調用者必須是一個線程,
例如:
Thread t = new CustomThread();//這里一般是自定義的線程類
t.start();//線程起動
t.join();//此處會拋出InterruptedException異常
2.上面的兩行代碼也是在一個線程里面執行的。
以上出現了兩個線程,一個是我們自定義的線程類,我們實現了run方法,做一些我們需要的工作;另外一個線程,生成我們自定義線程類的對象,然后執行
customThread.start();
customThread.join();
在這種情況下,兩個線程的關系是一個線程由另外一個線程生成并起動,所以我們暫且認為第一個線程叫做“子線程”,另外一個線程叫做“主線程”。
二、為什么要用join()方法
主線程生成并起動了子線程,而子線程里要進行大量的耗時的運算(這里可以借鑒下線程的作用),當主線程處理完其他的事務后,需要用到子線程的處理結果,這個時候就要用到join();方法了。
三、join方法的作用
在網上看到有人說“將兩個線程合并”。這樣解釋我覺得理解起來還更麻煩。不如就借鑒下API里的說法:
“等待該線程終止。”
解釋一下,是主線程(我在“一”里已經命名過了)等待子線程的終止。也就是在子線程調用了join()方法后面的代碼,只有等到子線程結束了才能執行。(Waits for this thread to die.)
四、用實例來理解
寫一個簡單的例子來看一下join()的用法,一共三個類:
1.CustomThread 類
2. CustomThread1類
3. JoinTestDemo 類,main方法所在的類。
代碼1:
打印結果:
main start.//main方法所在的線程起動,但沒有馬上結束,因為調用t.join();,所以要等到t結束了,此線程才能向下執行。
[CustomThread1] Thread start.//線程CustomThread1起動
[CustomThread1] Thread loop at 0//線程CustomThread1執行
[CustomThread1] Thread loop at 1//線程CustomThread1執行
[CustomThread] Thread start.//線程CustomThread起動,但沒有馬上結束,因為調用t1.join();,所以要等到t1結束了,此線程才能向下執行。
[CustomThread1] Thread loop at 2//線程CustomThread1繼續執行
[CustomThread1] Thread loop at 3//線程CustomThread1繼續執行
[CustomThread1] Thread loop at 4//線程CustomThread1繼續執行
[CustomThread1] Thread end. //線程CustomThread1結束了
[CustomThread] Thread end.// 線程CustomThread在t1.join();阻塞處起動,向下繼續執行的結果
main end!//線程CustomThread結束,此線程在t.join();阻塞處起動,向下繼續執行的結果。
修改一下代碼,得到代碼2:(這里只寫出修改的部分)
main start. // main方法所在的線程起動,但沒有馬上結束,這里并不是因為join方法,而是因為Thread.sleep(2000);
[CustomThread1] Thread start. //線程CustomThread1起動
main end!// Thread.sleep(2000);結束,雖然在線程CustomThread執行了t1.join();,但這并不會影響到其他線程(這里main方法所在的線程)。
[CustomThread] Thread start. //線程CustomThread起動,但沒有馬上結束,因為調用t1.join();,所以要等到t1結束了,此線程才能向下執行。
[CustomThread] Thread end. // 線程CustomThread在t1.join();阻塞處起動,向下繼續執行的結果
五、從源碼看join()方法
在CustomThread的run方法里,執行了t1.join();,進入看一下它的JDK源碼:
然后進入join(0)方法:
單純從代碼上看,如果線程被生成了,但還未被起動,調用它的join()方法是沒有作用的。將直接繼續向下執行,這里就不寫代碼驗證了。
----2009年02月12日
Powered by: BlogJava Copyright © 李 明