join
主线程启动子线程,需要等待子线程结束后,主线程才结束,这个时候可以用join。
- 可以调用join(long)设定等待时间
示例:
public class JoinTest {
private static class MythreadA extends Thread {
private Object object;
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(this.getName() + ":" + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
MythreadA threadA=new MythreadA();
threadA.start();
threadA.join();//后面的代码会等待threadA运行完之后再运行
System.out.println("after ThreadA ");
}
}
join与Interrupt
在线程B中调用的A的join方法,此时在C线程再调用B的Interrupt()方法。
结果:B线程停止等待A执行完成(或者成为打断A的join方法)。此时不会中断A的运行,A会持续运行
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;
}
}
}
从上面的代码可以看出,join其实调用的是wait(),即也具有wait释放锁的特点。
。 当main线程调用t.join时候,main线程会获得线程对象threadA的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程 ,比如退出后。这就意味着main 线程调用threadA.join时,必须能够拿到线程threadA对象的锁