一、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