第二章:簡單 Java 程式解析
第三章:變數與資料型態
第四章:運算子、運算式與敘述
第五章:選擇性敘述與迴圈
第十章:實例變數與函數、類別變數與函數
Powered By GitBook
凍結執行緒 join()
執行緒生命週期 中,被凍結的狀態提到的 sleep() 已在 凍結執行緒 sleep() 說明了用法,本篇將說明 join() 的用法。
凍結執行緒 sleep() 中的範例,兩個執行緒(apple, pen)可說是同時啟動的,那如果再啟動的下方再加上一行印出 main() 結束 的程式碼
1
apple.show();
2
pen.show();
3
System.out.println("main() 結束");
Copied!

完整程式碼(錯誤)

1
class multi_Test
2
{
3
private String name;
4
public multi_Test(String str)
5
{
6
name=str;
7
}
8
public void show()
9
{
10
for(int i=0;i<3;i++)
11
{
12
try
13
{
14
sleep((int)(1000*Math.random()));
15
}
16
catch(InterruptedException e){}
17
System.out.println(name);
18
}
19
}
20
}
21
22
public class multi_thread_3
23
{
24
public static void main(String args[])
25
{
26
multi_Test apple=new multi_Test("apple");
27
multi_Test pen=new multi_Test("pen");
28
apple.start();
29
pen.start();
30
System.out.println("main() 結束");
31
}
32
}
Copied!
當我們執行的結果會發現,會先印出「main() 結束」。
記得 main() 本身其實也是個執行緒,一樣是看誰先搶到資源。 但因為僅印出字串,不需要經過執行緒的啟動,因此通常較先搶到資源 先執行。
這麼一來若是先印出「 main() 結束」 就不是我們想要的目的; 我們想先apple 執行緒完成後再執行pen 執行緒, 等到兩個執行緒都結束才正式main() 結束(因此印出字串)。
想要達到這樣的結果,就必須使用到 join() 來處理執行緒的排程。
執行緒生命週期 中提到的觀念:
執行緒與另一個執行緒 join() 一起時: 當有其他執行緒呼叫 join(),原來正執行的執行緒(或程式碼)會先暫停
join() 必須寫在 try-catch 區塊內,因此我們可以將上述錯誤的程式這樣改寫:
當 apple 執行緒啟動 便進到try 後,apple執行緒結束後就會往下執行 啟動pen執行緒, 當pen 執行緒結束後 才會再往下執行 印出字串的程式。
1
apple.start();
2
try
3
{
4
apple.join();
5
pen.start();
6
pen.join();
7
}
8
catch(){}
9
System.out.println("main() 結束");
Copied!
在啟動 apple 執行緒後會先停留在 apple.join() 等待該執行緒完成,才會執行下一行程式(啟動pen執行緒); 同理 pen 執行緒會停留在 pen.join() ,等到執行緒結束後就會將字串「main() 結束」字串印出。
還有一點要注意的是, join() 會拋出 InterruptedException 例外 因此才必須將 join() 寫在 try-catch 區塊,而catch 要捕捉 InterruptedException 例外。
1
apple.start();
2
try
3
{
4
apple.join();
5
pen.start();
6
pen.join();
7
}
8
catch(InterruptedException e){}
9
System.out.println("main() 結束");
Copied!

完整程式碼(正確)

1
class multi_Test
2
{
3
private String name;
4
public multi_Test(String str)
5
{
6
name=str;
7
}
8
public void show()
9
{
10
for(int i=0;i<3;i++)
11
{
12
try
13
{
14
sleep((int)(1000*Math.random()));
15
}
16
catch(InterruptedException e){}
17
System.out.println(name);
18
}
19
}
20
}
21
22
public class multi_thread_3
23
{
24
public static void main(String args[])
25
{
26
multi_Test apple=new multi_Test("apple");
27
multi_Test pen=new multi_Test("pen");
28
apple.start();
29
try
30
{
31
apple.join();
32
pen.start();
33
pen.join();
34
}
35
catch(InterruptedException e){}
36
System.out.println("main() 結束");
37
}
38
}
Copied!
Last modified 9mo ago