前文
使用Thread 的join方法,可以协调线程运行顺序。
一、join介绍
定义在Thread类
public final void join() throws InterruptedException ;
public final synchronized void join(long millis)throws InterruptedException ;
public final synchronized void join(long millis, int nanos)throws InterruptedException
join的大概意思是,让主线程等待子线程结束之后才能继续运行
二、代码示例
package wang.conge.javasedemo.core.thread;
/**
* [[[@author](http://my.oschina.net/arthor)](http://my.oschina.net/arthor)](http://my.oschina.net/arthor) conge
* 2016年7月21日
*/
public class JoinDemo {
public static void main(String[] args) {
System.out.println("main thread start");
Thread childThread = new Thread(()->{
System.out.println("child thread start");
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("child thread end");
});
childThread.start();
try {
childThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main thread end");
}
}
运行结果:
main thread start
child thread start
child thread end
main thread end
三、原理解释
从源代码看
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;
}
}
}
参开上面的demo代码,大概意思是:
- main线程先运行,输出'main thread start'
- child线程启动后运行。此时main线程和child线程有平等机会获取CPU执行权
- main线程调用方法:child.join()。
- 这个child.join(),不是child线程调用,而是main线程调用child线程对象的方法,这句很重要。isAlive(),然后main线程不停的循环判断child线程是否存活。如果child线程存活,那么main线程一直等待,其实就是main让出了CPU执行权。
- 等child线程执行完之后,main线程判断isAlive()为false,然后继续执行main线程下面的逻辑
四、总结
join方法用途在于主线程需要先等待子线程先执行完任务,然后主线程进行合并执行后的结果。