重點:
1.join()的作用是讓“主線程”等待“子線程”結(jié)束之后才能繼續(xù)運行
2.wait()的作用是讓“當(dāng)前線程”等待烁巫,而這里的“當(dāng)前線程”是指當(dāng)前在CPU上運行的線程。所以甥角,雖然是調(diào)用子線程的wait()方法,但是它是通過“主線程”去調(diào)用的纱兑;所以因俐,休眠的是主線程,而不是“子線程”妄呕!
正文部分:
package thread;
public class MyThread1 extends Thread {
private String name;
public MyThread1(String name) {
this.name = name;
}
@Override
public void run(){
System.out.println(name+"運行");
}
public static void main(String[] args) throws InterruptedException {
MyThread1 myThreadA = new MyThread1("A");
MyThread1 myThreadB = new MyThread1("B");
MyThread1 myThreadC = new MyThread1("C");
myThreadA.start();
/**join的意思是使得放棄當(dāng)前線程的執(zhí)行陶舞,并返回對應(yīng)的線程,例如下面代碼的意思就是:
程序在main線程中調(diào)用t1線程的join方法绪励,則main線程放棄cpu控制權(quán)肿孵,并返回t1線程繼續(xù)執(zhí)行直到線程t1執(zhí)行完畢
所以結(jié)果是t1線程執(zhí)行完后,才到主線程執(zhí)行疏魏,相當(dāng)于在main線程中同步t1線程停做,t1執(zhí)行完了,main線程才有執(zhí)行的機會
*/
myThreadA.join();
myThreadB.start();
myThreadB.join();
myThreadC.start();
}
}
- join()源碼分析(基于JDK1.7.0_40)
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
說明:
從代碼中大莫,我們可以發(fā)現(xiàn)蛉腌。當(dāng)millis==0時,會進入while(isAlive())循環(huán)只厘;即只要子線程是活的烙丛,主線程就不停的等待。
我們根據(jù)上面解釋join()作用時的代碼來理解join()的用法羔味!
問題:
雖然s.join()被調(diào)用的地方是發(fā)生在“Father主線程”中河咽,但是s.join()是通過“子線程s”去調(diào)用的join()。那么赋元,join()方法中的isAlive()應(yīng)該是判斷“子線程s”是不是Alive狀態(tài)忘蟹;對應(yīng)的wait(0)也應(yīng)該是“讓子線程s”等待才對。但如果是這樣的話们陆,s.join()的作用怎么可能是“讓主線程等待寒瓦,直到子線程s完成為止”呢,應(yīng)該是讓"子線程等待才對(因為調(diào)用子線程對象s的wait方法嘛)"坪仇?
答案:wait()的作用是讓“當(dāng)前線程”等待杂腰,而這里的“當(dāng)前線程”是指當(dāng)前在CPU上運行的線程。所以椅文,雖然是調(diào)用子線程的wait()方法喂很,但是它是通過“主線程”去調(diào)用的惜颇;所以,休眠的是主線程少辣,而不是“子線程”凌摄!
結(jié)果說明:
運行流程如圖
(01) 在“主線程main”中通過 new ThreadA("t1") 新建“線程t1”。 接著漓帅,通過 t1.start() 啟動“線程t1”锨亏,并執(zhí)行t1.join()。
(02) 執(zhí)行t1.join()之后忙干,“主線程main”會進入“阻塞狀態(tài)”等待t1運行結(jié)束器予。“子線程t1”結(jié)束之后捐迫,會喚醒“主線程main”乾翔,“主線程”重新獲取cpu執(zhí)行權(quán),繼續(xù)運行施戴。