1 join使用方式
若主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据中的值,就要用到join
,它的作用是等待线程对象销毁。
public class MyThread extends Thread {
@Override
public void run() {
try {
int secondVal = (int) (Math.random() * 10000);
System.out.println(secondVal);
Thread.sleep(secondVal);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
try {
MyThread myThread = new MyThread();
myThread.start();
myThread.join();
System.out.println("等myThread对象执行完毕后,再执行这句");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
方法join
的作用是是使所属的线程对象x
正常执行run()
方法中的任务,而使当前线程z
进行无限期的阻塞,等待线程x
销毁后再执行线程z
后面的代码。
join
与synchronized
的区别是:join
在内部使用wait()
方法进行等待,而synchronized
关键字使用的是“对象监视器”原理做同步
1.1 join与异常
在join
的过程中,如果当前线程对象被中断,则当前线程出现异常。
1.2 方法join(long)与sleep(long)的区别
方法join(long)
的功能在内部是使用wait(long)
方法来实现的,所以join(long)
方法具有释放锁的特点,而sleep(long)
方法不释放锁。
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;
}
}
}