在项目实践中经常会遇到一个场景,就是需要等待某几件事情完成后才能继续往下执行,比如多个线程加载资源,需要等待多个线程全部加载完毕再汇总处理。Thread类中有一个join方法就可以做这个事情,join方法则是Thread类直接提供的。join是无参且返回值为void的方法。
正常示例
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("child threadOne over!");
}
});
Thread threadTwo = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("child threadTwo over!");
}
});
threadOne.start();
threadTwo.start();
System.out.println("wait all child thread over!");
// 等待子线程执行完,返回
threadOne.join();
threadTwo.join();
System.out.println("all child thread over!");
}
}
wait all child thread over!
child threadOne over!
child threadTwo over!
all child thread over!
根据程序执行结果, 主线程的两条打印语句在子线程的前后, 说明在主线程中执行threadOne.join()语句, 当前主线程会阻塞, 等待子线程执行完, 接着往下执行.
join 中断示例
阻塞的线程, 如果被其他线程执行了interrupt() 方法会报InterruptedException 异常
public class JoinInterruptedExceptionTest {
public static void main(String[] args) {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("child threadOne begin run!");
// threadOne 放一个死循环
for (;;) {
}
}
});
// 获取主线程
final Thread mainThread = Thread.currentThread();
Thread threadTwo = new Thread(new Runnable() {
@Override
public void run() {
// threadTwo 上来就休眠1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 中断主线程
mainThread.interrupt();
}
});
threadOne.start();
threadTwo.start();
try {
threadOne.join();
} catch (InterruptedException e) {
System.out.println("main thread:" + e);
}
}
}
child threadOne begin run!
main thread:java.lang.InterruptedException
执行结果: 主线程被中断了, 主线程一直在等待threadOne 执行结束, 但threadOne是死循环, 当threadTwo 中断main线程时就会报中断异常.
评论