public class JoinDetail extends Thread{
public JoinDetail(String name) {
super(name);
}
@Override
public void run() {
long a = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "start");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
a = System.currentTimeMillis() - a;
System.out.println(Thread.currentThread().getName() + "end" + a);
}
public static void main(String[] args) {
long currentTime = System.currentTimeMillis();
JoinDetail j1 = new JoinDetail("j1");
HaveThreadLock j2 = new HaveThreadLock("j2",j1);
j1.start();
j2.start();
/*
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
try {
j1.join(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主線程執(zhí)行完畢");
System.out.println("總共耗時(shí)" + (System.currentTimeMillis() - currentTime));
}
}
執(zhí)行結(jié)果
j2begin
j1start
j2end5000
主線程執(zhí)行完畢
總共耗時(shí)5002
j1end10000
將注釋
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
打開(kāi)
執(zhí)行結(jié)果
j2begin
j1start
j2end5001
主線程執(zhí)行完畢
總共耗時(shí)8004
j1end10001
join方法
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;
}
}
}
線程1調(diào)用線程2的join方法部凑,會(huì)把線程2對(duì)象本身當(dāng)作syschronized鎖對(duì)象喉磁,獲取到了鎖然后再判斷線程2的alive狀態(tài)并且wait姿鸿。
分析結(jié)果
在注釋情況下履腋,main線程首先獲取j1對(duì)象鎖,然后給join方法中的base賦值危彩,wait釋放鎖徒欣,使j2線程獲取到鎖逐样,sleep5秒,然后main線程wait時(shí)間超時(shí)重新獲取j1鎖發(fā)現(xiàn)delay<0了打肝,接著main線程結(jié)束脂新。
在打開(kāi)注釋情況下,j2線程先獲取j1對(duì)象鎖粗梭,sleep5秒争便,然后main線程調(diào)用j1.join,wait5秒断医,接著main線程結(jié)束滞乙。