Thread中,join()方法的作用是調用線程等待該線程完成后,才能繼續用下運行。
public static void main(String[] args) throws InterruptedException { System.out.println("main start"); Thread t1 = new Thread(new Worker("thread-1")); t1.start(); t1.join(); System.out.println("main end"); }
在上面的例子中,main線程要等到t1線程運行結束后,才會輸出“main end”。如果不加t1.join(),main線程和t1線程是並行的。而加上t1.join(),程序就變成是順序執行了。
我們在用到join()的時候,通常都是main線程等到其他多個線程執行完畢后再繼續執行。其他多個線程之間並不需要互相等待。
下面這段代碼並沒有實現讓其他線程並發執行,線程是順序執行的。
public static void main(String[] args) throws InterruptedException { System.out.println("main start"); Thread t1 = new Thread(new Worker("thread-1")); Thread t2 = new Thread(new Worker("thread-2")); t1.start(); //等待t1結束,這時候t2線程並未啟動 t1.join(); //t1結束后,啟動t2線程 t2.start(); //等待t2結束 t2.join(); System.out.println("main end"); }
為了讓t1、t2線程並行,我們可以稍微改一下代碼,下面給出完整的代碼:
public class JoinTest { public static void main(String[] args) throws InterruptedException { System.out.println("main start"); Thread t1 = new Thread(new Worker("thread-1")); Thread t2 = new Thread(new Worker("thread-2")); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("main end"); } } class Worker implements Runnable { private String name; public Worker(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 10; i++) { try { Thread.sleep(1l); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name); } } }
thread的六種狀態
線程共有6種狀態;在某一時刻只能是這6種狀態之一。這些狀態由Thread.State這個枚舉類型表示,並且可以通過getState()方法獲得當前具體的狀態類型。
NEW
至今尚未啟動的線程的狀態。
當使用new一個新線程時,如new Thread(r),但還沒有執行start(),線程還沒有開始運行,這時線程的狀態就是NEW。
RUNNABLE
可運行線程的線程狀態。
當start()方法被調用時,線程就進入RUNNABLE狀態。此時的線程可能正在運行,也可能沒有運行
BLOCKED
受阻塞並且正在等待監視器鎖的某一線程的線程狀態。
下列情況會進入阻塞狀態:
1.等待某個操作的返回,例如IO操作,該操作返回之前,線程不會繼續下面的代碼。
2.等待某個“鎖”,在其他線程或程序釋放這個“鎖”之前,線程不會繼續執行。
3.等待一定的觸發條件。
4.線程執行了sleep方法。
5.線程被suspend()方法掛起。
一個被阻塞的線程在下列情況下會被重新激活:
1.執行了sleep()方法,睡眠時間已到。
2.等待的其他線程或程序持有的“鎖”已被釋放。
3.正在等待觸發條件的線程,條件得到滿足。
4.執行了suspend()方法,被調用了resume()方法。
5.等待的操作返回的線程,操作正確返回。
WAITING
某一等待線程的線程狀態。
線程因為調用了Object.wait()或Thread.join()而未運行,就會進入WAITING狀態。
TIMED_WAITING
具有指定等待時間的某一等待線程的線程狀態。
線程因為調用了Thread.sleep(),或者加上超時值來調用Object.wait()或Thread.join()而未運行,則會進入TIMED_WAITING狀態。
TERMINATED
已終止線程的線程狀態。
線程已運行完畢。它的run()方法已正常結束或通過拋出異常而結束。
線程的終止
run()方法結束,線程就結束。
NEW
至今尚未啟動的線程的狀態。
當使用new一個新線程時,如new Thread(r),但還沒有執行start(),線程還沒有開始運行,這時線程的狀態就是NEW。
RUNNABLE
可運行線程的線程狀態。
當start()方法被調用時,線程就進入RUNNABLE狀態。此時的線程可能正在運行,也可能沒有運行
BLOCKED
受阻塞並且正在等待監視器鎖的某一線程的線程狀態。
下列情況會進入阻塞狀態:
1.等待某個操作的返回,例如IO操作,該操作返回之前,線程不會繼續下面的代碼。
2.等待某個“鎖”,在其他線程或程序釋放這個“鎖”之前,線程不會繼續執行。
3.等待一定的觸發條件。
4.線程執行了sleep方法。
5.線程被suspend()方法掛起。
一個被阻塞的線程在下列情況下會被重新激活:
1.執行了sleep()方法,睡眠時間已到。
2.等待的其他線程或程序持有的“鎖”已被釋放。
3.正在等待觸發條件的線程,條件得到滿足。
4.執行了suspend()方法,被調用了resume()方法。
5.等待的操作返回的線程,操作正確返回。
WAITING
某一等待線程的線程狀態。
線程因為調用了Object.wait()或Thread.join()而未運行,就會進入WAITING狀態。
TIMED_WAITING
具有指定等待時間的某一等待線程的線程狀態。
線程因為調用了Thread.sleep(),或者加上超時值來調用Object.wait()或Thread.join()而未運行,則會進入TIMED_WAITING狀態。
TERMINATED
已終止線程的線程狀態。
線程已運行完畢。它的run()方法已正常結束或通過拋出異常而結束。
線程的終止
run()方法結束,線程就結束。
