/**
* * join()方法解釋:
* 一個線程可以在其他線程之上調用Join()方法,其效果是等待一段時間直到第二個線程結束才繼續執行。
* 如果某個線程在另一個線程t上調用t.join(),此線程將被掛起,直到目標線程t結束才恢復
* (即t.isAlive()返回爲假)。
* 也可以在調用join()時帶上一個超時參數(單位可以是毫秒,或者毫秒和納秒),
* 這樣如果目標線程在這段時間到期時還沒有結束的話,join()方法總能返回。
* 對join()方法的調用可以被中斷,做法實是在調用線程上調用interrupt()方法,
* 這時需要調用try-catch子句。
*/
/**
* Sleeper 是一個Thread類型,它需要休眠一段時間,這段時間是通過構造器傳進來的參數所指定的。
* 在run()中,sleep()方法有可能在指定的時間期滿時返回,但也可能被中斷。
* 在catch子句中,將根據isInterrpted()的返回值報告這個中斷。當另一個線程在該線程上調用interrupt()時,
* 將給該線程設定一個標誌,表明該線程已經被中斷。然而,異常被捕獲時將清理這個標誌,
* 所以在catch子句中,在異常被捕獲的時候這個標誌總是爲假。除異常之外,這個標誌還可用於其他情況,
* 比如線程可能會檢查其中斷狀態。
*
* @create @author Henry @date 2016-11-23
*
*/
class Sleeper extends Thread {
private int duration;
public Sleeper(String name, int sleepTime) {
super(name);
duration = sleepTime;
start();
}
@Override
public void run() {
try {
sleep(duration);
System.out.println("world");
} catch (InterruptedException e) {
System.out.println(getName() + " was interrupted. IsInterrupted():" + isInterrupted());
return;
}
System.out.println(getName() + " has awakened");
}
}
/**
* Joiner 線程將通過在Sleeper對象上調用join()方法來等待Sleeper醒來。
*
* @create @author Henry @date 2016-11-23
*
*/
class Joiner extends Thread {
private Sleeper sleeper;
public Joiner(String name, Sleeper sleeper) {
super(name);
this.sleeper = sleeper;
start();
}
@Override
public void run() {
try {
sleeper.join();
} catch (InterruptedException e) {
System.out.println("Interrupted---");
}
System.out.println(getName() + " join completed");
}
}
/**
* 在main()裏面,每個Sleeper都有一個Joiner,這個可以在輸出中發現,
* 如果sleeper被中斷或者正常結束,Joiner將和Sleeper一同結束。
*
* @create @author Henry @date 2016-11-23
*
*/
public class Joining {
public static void main(String[] args) {
Sleeper sleepy = new Sleeper("Sleepy", 1500), grumpy = new Sleeper("Grumpy", 1500);
Joiner dopey = new Joiner("Dopey", sleepy), doc = new Joiner("Doc", grumpy);
System.out.println("hello");
grumpy.interrupt();
}
}
控制檯結果:
hello
Grumpy was interrupted. IsInterrupted():false
Doc join completed
world
Sleepy has awakened
Dopey join completed