什么是join()方法:在Thread.java中定义,作用是让当前线程等待子线程运行结束之后才能继续运行
一 源码分析:
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;
}
}
}
从源码分析,可以得到:传入的时间millis==0的时候,wait(0)即无限等待.join方法会判断,当前进程是否还在活动,isAlive()方法就是判断进程是否处于活动状态。如果传入时间等于0,就会阻塞当前进程。
这里有个注意重点:乍一看代码,明明是子线程调用join()方法的时候,判断子线程是否活动状态,让子线程等待才对,哪里是让主线程等待了?
解答:要理解清楚wait()方法的作用,wait()方法的作用是让当前进程阻塞,当前线程是指处于CPU上运行的线程,不在CPU上运行的不能叫当前线程。当子线程在父线程中启动之后,由于子线程是通过父线程调用方法的,如果父线程没有在cpu上运行,那么子线程肯定没法调用方法,所以这时在CPU上运行的是父线程,所以休眠的是父线程,不是子线程。
举例:
// JoinTest.java的源码
public class JoinTest{
public static void main(String[] args){
try {
ThreadA t1 = new ThreadA("t1"); // 新建“线程t1”
t1.start(); // 启动“线程t1”
t1.join(); // 将“线程t1”加入到“主线程main”中,并且“主线程main()会等待它的完成”
System.out.printf("%s finish\n", Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class ThreadA extends Thread{
public ThreadA(String name){
super(name);
}
public void run(){
System.out.printf("%s start\n", this.getName());
// 延时操作
for(int i=0; i <1000000; i++)
;
System.out.printf("%s finish\n", this.getName());
}
}
}