Java多线程8-join()
1、join()介绍
join()定义在Thread.java中。join()的作用为:让“主线程”等待“子线程”结束之后才能继续运行。
示例:
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
结果说明:
father主线程在创建子线程son后执行,在执行了一条语句过后,s.join()开始执行,所以father必须等待son执行完毕过后才能执行
2、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())循环;即只要子线程是活的,主线程就一直等待
问题:虽然s.join()背调用的地方在father主线程中,但是s.join()是通过“子线程s”去调用的join(),这样应该判断子线程是不是alive状态,也应该让子线程wait,为什么可以让主线程等待?
答案:wait()的作用是让当前线程等待,这里的当前线程是指CPU上运行的线程。所以,虽然是调用子线程的wait()方法,但是是主线程调用的,所以主线程休眠