在大多數狀況下,主線程建立並啓動子線程,若是子線程中要進行大量的耗時計算,主線程每每會在子線程結束以前結束掉。如果主線程想要等待子線程執行完成以後再結束,則必須用到方法join().java
方法join()的做用爲:等待線程對象銷燬。this
首先先看一個join方法的例子線程
public class MyThread extends Thread { private static int number = 0; public void run(){ while(number < 1000){ number++; } } public static void main(String [] args){ MyThread t1 = new MyThread(); t1.start(); t1.join(); System.out.println(number); } } 運行結果:1000
在此例中,由於在當前線程------主線程中調用了t1線程的join方法,因此主線程必須等到子線程結束以後才能夠繼續運行。code
方法join的做用是使所屬的線程對象x正常執行run方法中的任務,而使當前線程z進行無限期的阻塞,等待線程x銷燬以後再繼續進行線程z後面的代碼。對象
方法join具備使線程排隊運行的做用,有些相似於同步效果。但join與synchronized的區別是:join方法在內部使用wait方法進行等待,而synchronized關鍵字使用的是對象監視器原理做爲同步。同步
若join方法遇到interrupt方法,則當前線程會拋出異常。即:在join過程當中,若是當前線程被打斷,則當前線程出現異常。it
public class ThreadA extends Thread { public void run(){ int i = 0; while(true) { i++; } } } public class ThreadB extends Thread { public void run(){ try{ Thread a = new ThreadA(); a.start(); a.join(); }catch(InterruptedException e){ System.out.println("catch"); } } } public class ThreadC extends Thread { private ThreadB b; public ThreadC(ThreadB b){ this.b = b; } public void run(){ b.interrupt(); } } public class Run { public static void main(String [] args){ ThreadB b = new ThreadB(); b.start(); Thread.sleep(5000); ThreadC c = new ThreadC(b); c.start(); } } 運行結果:catch
分析:在當前線程join過程(即在當前線程中調用了join方法)中時,當前線程b又調用了interrupt方法,因此拋出異常。可是a線程仍然一直在運行。io
方法join(long)的使用class
sleep(long)與join(long)的區別就在與這裏兩個方法對於同步的不一樣處理上。join方法內部是由wait方法實現,因此在執行完join(long)方法後,當前線程會釋放鎖,而Thread.sleep(long)則不會釋放鎖。原理