Blocks the current Thread (<code>Thread.currentThread()</code>) until the receiver finishes its execution and dies.
@throws InterruptedException if <code>interrupt()</code> was called for the receiver while it was in the <code>join()</code> call
@see Object#notifyAll
@see java.lang.ThreadDeath
join方法的注釋上寫著:阻塞當前線程,直到收到結束執行或者死亡。當接收者的interrupt方法被調用,并且它被調用了join方法的時候,就會拋出InteruptedException。
舉個例子:線程A的run方法中調用了線程B的join,此時線程A處于阻塞狀態,直到線程B執行完畢或者死亡的時候,線程A才會繼續執行。如果此時線程A處于阻塞狀態,而線程B調用線程A的interrupt的時候,就會拋出InterruptedException。
下面舉兩個例子
示例1:
有兩個線程A,B,在A的run方法中,會調用ThreadB.join,也就是說,在ThreadA啟動之后,打印出來"ThreadA Started"之后,就會被線程B阻塞。然后線程B開始執行,打印出來"ThreadB started"之后,會休眠5S,之后再打印出"ThreadB Sleep End",之后線程B執行結束,于是線程A阻塞解除,打印出"ThreadA End"。
public class Test {
public static void main(String[] args) {
ThreadB threadB = new ThreadB();
ThreadA threadA = new ThreadA(threadB);
threadA.start();
threadB.start();
}
private static class ThreadA extends Thread {
ThreadB joinThread;
ThreadA(ThreadB threadB) {
joinThread = threadB;
}
@Override
public void run() {
super.run();
System.out.println("ThreadA Started");
try {
joinThread.join();
} catch (InterruptedException e) {
}
System.out.println("ThreadA End");
}
}
private static class ThreadB extends Thread {
@Override
public void run() {
super.run();
System.out.println("ThreadB started");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadB Sleep End");
}
}
}
運行結果:
示例2
和上例不一樣的地方是,在ThreadB的Run方法中,Sleep完后,調用ThreadA.interrupt,試一下官方文檔上注釋對不對。
public class Test {
public static void main(String[] args) {
ThreadB threadB = new ThreadB();
ThreadA threadA = new ThreadA(threadB);
threadB.setThreadA(threadA);
threadA.start();
threadB.start();
}
private static class ThreadA extends Thread {
ThreadB joinThread;
ThreadA(ThreadB threadB) {
joinThread = threadB;
}
@Override
public void run() {
super.run();
System.out.println("ThreadA Started");
try {
joinThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadA End");
}
}
private static class ThreadB extends Thread {
ThreadA threadA;
public void setThreadA(ThreadA threadA) {
this.threadA = threadA;
}
@Override
public void run() {
super.run();
System.out.println("ThreadB started");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadB Call ThreadA.interrupt");
threadA.interrupt();
System.out.println("ThreadB Sleep End");
}
}
}
運行結果:
打印出InterruptedException