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("主线程执行完毕");
System.out.println("总共耗时" + (System.currentTimeMillis() - currentTime));
}
}
执行结果
j2begin
j1start
j2end5000
主线程执行完毕
总共耗时5002
j1end10000
将注释
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
打开
执行结果
j2begin
j1start
j2end5001
主线程执行完毕
总共耗时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调用线程2的join方法,会把线程2对象本身当作syschronized锁对象,获取到了锁然后再判断线程2的alive状态并且wait。
分析结果
在注释情况下,main线程首先获取j1对象锁,然后给join方法中的base赋值,wait释放锁,使j2线程获取到锁,sleep5秒,然后main线程wait时间超时重新获取j1锁发现delay<0了,接着main线程结束。
在打开注释情况下,j2线程先获取j1对象锁,sleep5秒,然后main线程调用j1.join,wait5秒,接着main线程结束。