一、join()介绍java
join()定义在Thread.java中。join()的做用为:让“主线程”等待“子线程”结束以后才能继续运行。源码分析
示例:spa
public class Father extends Thread { public static void main(String[] args) { Father f = new Father(); f.start(); } public void run() { Son s = new Son(); s.start(); for(int i = 0;i < 5;i++) System.out.println("father thread "+i); try { s.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } class Son extends Thread { public void run() { for(int i = 0;i < 5;i++) System.out.println("son thread "+i); } }
运行结果:线程
father thread 0 son thread 0 son thread 1 son thread 2 son thread 3 son thread 4 father thread 1 father thread 2 father thread 3 father thread 4
结果说明:code
father主线程在建立子线程son后执行,在执行了一条语句事后,s.join()开始执行,因此father必须等待son执行完毕事后才能执行blog
二、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时,会进入while(isAlive())循环;即只要子线程是活的,主线程就一直等待it
问题:虽然s.join()背调用的地方在father主线程中,可是s.join()是经过“子线程s”去调用的join(),这样应该判断子线程是否是alive状态,也应该让子线程wait,为何能够让主线程等待?io
答案:wait()的做用是让当前线程等待,这里的当前线程是指CPU上运行的线程。因此,虽然是调用子线程的wait()方法,可是是主线程调用的,因此主线程休眠class