From Gossip@Openhome

Java Gossip: 執行緒的加入(join)

如果有一個A執行緒正在運行,您希望插入一個B執行緒,並要求B執行緒先執行完畢,然後再繼續A執行緒的流程,您可以使用 join()方法來完成這個需求,這就好比您手頭上正有一個工作在進行,老闆插入一個工作要求您先作好,然後再進行您原先正進行的工作。

當執行緒使用join()加入至另一個執行緒時,另一個執行緒會等待這個被加入的執行緒工作完畢,然後再繼續它的動作,使用下面這個簡單的例子就可以 說明:

  • ThreadA.java
package onlyfun.caterpillar;

public class ThreadA {
public static void main(String[] args) {
System.out.println("Thread A 執行");

Thread threadB = new Thread(new Runnable() {
public void run() {
try {
System.out.println("Thread B 開始..");
for(int i = 0; i < 5; i++) {
Thread.sleep(1000);
System.out.println("Thread B 執行..");
}
System.out.println("Thread B 即將結束..");
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
});

threadB.start();

try {
// Thread B 加入 Thread A
threadB.join();
}
catch(InterruptedException e) {
e.printStackTrace();
}

System.out.println("Thread A 執行");
}
}

程式啟動後主執行緒就開始,在主執行緒中您新建threadB,並在啟動threadB後,將之加入(join)主執行緒的流程之中,threadB必須 先執行完畢,主執行緒才會再繼續它原本的流程, 執行結果如下:
Thread A 執行
Thread B 開始..
Thread B 執行..
Thread B 執行..
Thread B 執行..
Thread B 執行..
Thread B 執行..
Thread B 即將結束..
Thread A 執行


如果程式中沒有將threadB使用join()將之加入主執行緒的流程中,則最後一行顯示"Thread A 執行"的陳述會先執行完畢(因為threadB使用了sleep(),這讓主執行緒有機會取得時間來執行)。

有時候這個加入的執行緒有可能處理太久,您不想無止境的等待這個執行緒的工作完畢,則您可以在join()上指定時間,例如 join(10000),表示至多等待10000毫秒,也就是10秒,如果加入的執行緒還沒執行完畢就不管它,目前的執行緒可以繼續執行工作。