title:join方法
date:2017年11月11日23:28:13
今天来简单看一下join()方法,
join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行。
直接上代码:
package com.wangcc.MyJavaSE.thread.join;
public class JoinTest {
public static void main(String []args) throws InterruptedException {
Thread t1=new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"start");
try {
Thread.sleep(2000);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println(Thread.currentThread().getName()+"finish");
}
},"t1");
t1.start();
t1.join();
System.out.println("main .....");
}
}
输出:
t1start
t1finish
main .....
我们看到主线程 在执行了t1.join()之后就把cpu让给了t1,直到t1结束,主线程才继续获得CPU执行下去。
那这是怎么做到的呢?这时我们就得看看join()方法到底做了什么。
public final void join() throws InterruptedException {
join(0);
}
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;
}
}
}
我们主要看这几行
if (millis == 0) {
while (isAlive()) {
wait(0);
}
当t1还活着的时候,就一直调用wait(0)阻塞线程。那这里到底阻塞的是t1还是Main Thread呢?显然从结果上看是阻塞Main Thread。但是我们不是调用的t1.wait()吗,为什么不是阻塞t1呢?这里其实你只要明白wait()的真正作用就可以了,我们知道wait()是Object类的方法,它阻塞的线程是当前持有该对象的线程。这里是调用t1.wait(),也就是阻塞了持有t1对象的线程。那么持有t1对象的线程在这里自然是Main Thread。
我们分析下代码:
首先,在主线程里创建了t1对象实例,主线程持有了t1,然后在主线程里执行t1.start();执行了t1.start()之后,t1线程处于就绪态,此时t1和Main Thread两个线程在争夺CPU资源,然后在某一时刻CPU资源重新回到了主线程之后,就会继续执行代码t1.join();注意了,是主线程执行的这行代码,所以此时就阻塞了主线程这个持有t1的线程,直到t1执行完成之后,退出循环,不再阻塞,线程重新转入就绪状态,此时只有主线程一个线程,获得CPU,从就绪态转入运行状态,继续执行主线程,就得到了上面的输出结果。