run() 和start() 是大家都很熟悉的兩個方法。把希望平行處理的代碼都放在run() 中;stat() 用於自動調用run(),這是JAVA的內在機制規定的。並且run() 的存取控制符必須是public,傳回值必須是void(這種說法不準確,run() 沒有傳回值),run()不帶參數。
閑話少說,我們要講的是join(),我們首先來看個例子:
代碼: /** * @author QingHe * Creation on 2005-12-19 */public class ThreadTest implements Runnable { public static int a = 0; public void run() { for (int k = 0; k < 5; k++) { a = a + 1; } } public static void main(String[] args) throws Exception { Runnable r = new ThreadTest(); Thread t = new Thread(r); t.start(); System.out.println(a); } }
|
|
請問程式的輸出結果是5嗎?答案是:有可能。其實你很難遇到輸出5的時候,通常情況下都不是5。當然這也和機器有嚴重的關係。為什麼呢?我的解釋是當主線程main方法執行System.out.println(a);這條語句時,線程還沒有真正開始運行,或許正在為它分配資源準備運行吧。因為為線程分配資源需要時間,而main方法執行完t.start()方法後繼續往下執行System.out.println(a);,這個時候得到的結果是a還沒有被改變的值0。怎樣才能讓輸出結果為5!其實很簡單,join() 方法提供了這種功能。join()
方法,它能夠使調用該方法的線程在此之前執行完畢。
代碼: /** * @author QingHe * Creation on 2005-12-19 */public class ThreadTest implements Runnable { public static int a = 0; public void run() { for (int k = 0; k < 5; k++) { a = a + 1; } } public static void main(String[] args) throws Exception { Runnable r = new ThreadTest(); Thread t = new Thread(r); t.start(); t.join(); System.out.println(a); } }
|
|
這個時候,程式輸入結果始終為5。
為了證明如果不使用t.join()方法,主線程main方法的System.out.println(a);語句將搶先執行,我們可以在main方法中加入一個迴圈,這個迴圈用來延長main方法執行的時間,迴圈次數將嚴重取決於機器效能。如果迴圈次數得當,我們也可以看到a的輸出結果是5。
代碼:
/** * @author QingHe * Creation on 2005-12-19 */ public class ThreadTest implements Runnable { public static int a = 0; public void run() { for (int k=0; k<5; k++) { a = a + 1; } } public static void main(String[] args) throws Exception { Runnable r = new ThreadTest(); Thread t = new Thread(r); t.start(); for (int i=0; i<300; i++) { /* 注意迴圈體內一定要有實際執行語句,否則編譯器或JVM可能最佳化掉你的這段代碼,視這段代 碼為無效。 */ System.out.print(i); } System.out.println(); System.out.println(a); } } |
|
這時,在我的機器上,a的輸出值始終為5。run() 和start() 是大家都很熟悉的兩個方法。把希望平行處理的代碼都放在run() 中;stat() 用於自動調用run(),這是JAVA的內在機制規定的。並且run() 的存取控制符必須是public,傳回值必須是void(這種說法不準確,run() 沒有傳回值),run()不帶參數。
閑話少說,我們要講的是join(),我們首先來看個例子:
代碼: /** * @author QingHe * Creation on 2005-12-19 */public class ThreadTest implements Runnable { public static int a = 0; public void run() { for (int k = 0; k < 5; k++) { a = a + 1; } } public static void main(String[] args) throws Exception { Runnable r = new ThreadTest(); Thread t = new Thread(r); t.start(); System.out.println(a); } }
|
|
請問程式的輸出結果是5嗎?答案是:有可能。其實你很難遇到輸出5的時候,通常情況下都不是5。當然這也和機器有嚴重的關係。為什麼呢?我的解釋是當主線程main方法執行System.out.println(a);這條語句時,線程還沒有真正開始運行,或許正在為它分配資源準備運行吧。因為為線程分配資源需要時間,而main方法執行完t.start()方法後繼續往下執行System.out.println(a);,這個時候得到的結果是a還沒有被改變的值0。怎樣才能讓輸出結果為5!其實很簡單,join() 方法提供了這種功能。join()
方法,它能夠使調用該方法的線程在此之前執行完畢。
代碼: /** * @author QingHe * Creation on 2005-12-19 */public class ThreadTest implements Runnable { public static int a = 0; public void run() { for (int k = 0; k < 5; k++) { a = a + 1; } } public static void main(String[] args) throws Exception { Runnable r = new ThreadTest(); Thread t = new Thread(r); t.start(); t.join(); System.out.println(a); } }
|
|
這個時候,程式輸入結果始終為5。
為了證明如果不使用t.join()方法,主線程main方法的System.out.println(a);語句將搶先執行,我們可以在main方法中加入一個迴圈,這個迴圈用來延長main方法執行的時間,迴圈次數將嚴重取決於機器效能。如果迴圈次數得當,我們也可以看到a的輸出結果是5。
代碼:
/** * @author QingHe * Creation on 2005-12-19 */ public class ThreadTest implements Runnable { public static int a = 0; public void run() { for (int k=0; k<5; k++) { a = a + 1; } } public static void main(String[] args) throws Exception { Runnable r = new ThreadTest(); Thread t = new Thread(r); t.start(); for (int i=0; i<300; i++) { /* 注意迴圈體內一定要有實際執行語句,否則編譯器或JVM可能最佳化掉你的這段代碼,視這段代 碼為無效。 */ System.out.print(i); } System.out.println(); System.out.println(a); } } |
|
這時,在我的機器上,a的輸出值始終為5。