引入
在很多情況下,主線程創建並啓動子線程,如果子線程要進行大量的耗時計算,主線程往往將早於子線程結束之前結束。這時,如果主線程想等待子線程執行完成之後再結束,比如子線程處理一個數據,主線程要取得這個數據的值,就要用到join()方法了。方法join()的作用是等待線程對象銷燬。
使用的主要的類
public class MyObject {
private int value;
public void setValue(int value){
System.out.println("set value:"+value);
this.value=value;
}
public int getValue(){
return value;
}
}
沒有使用join方法的情況
這種情況下演示,需求是主線程要在子線程給MyObject賦值後拿到MyObject對象的值,沒有使用join()方法會導致主線程會在子線程之前就結束。
子線程的代碼:
public class MyThread extends Thread{
private MyObject mo;
public MyThread(MyObject mo){
this.mo=mo;
}
public void run(){
mo.setValue(100);
}
}
運行的代碼
public class Run {
public static void main(String[] args) {
MyObject mo=new MyObject();
MyThread mt=new MyThread(mo);
mt.start();
int value=mo.getValue();
System.out.println("get value:"+value+" main thread end.");
}
}
運行結果爲:
get value:0 main thread end.
set value:100
2.用join()方法類解決
join()方法的作用是使所屬的線程對象x正常執行run()方法中的人物,而使當前線程z
進行無限期的阻塞,等待線程x銷燬後在繼續執行線程z後面的代碼。使線程具有排隊運行的作用,有着類似同步的運行效果。
public class Run {
public static void main(String[] args) {
try {
MyObject mo = new MyObject();
MyThread mt = new MyThread(mo);
mt.start();
mt.join(); //使用join()方法,先執行完mt線程的run方法中的任務
int value = mo.getValue();
System.out.println("get value:" + value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
運行結果:
set value:100
get value:100
其他注意的點
- 在join過程中,如果當前線程對象被中斷,則當前線程出現異常,InterruptedException。
- 方法join(long)中的參數是設置等待的時間。
- 方法join(long)的功能在內部是使用wait(long)方法來實現的,所以join(long)方法具有釋放鎖的特點,而Thread.sleep(long)方法具有不釋放鎖的特點。