thread.Join把指定的線程加入到當前線程,能夠將兩個交替執行的線程合併爲順序執行的線程。java
好比在線程B中調用了線程A的Join()方法,直到線程A執行完畢後,纔會繼續執行線程B。ide
t.join(); //調用join方法,等待線程t執行完畢
t.join(1000); //等待 t 線程,等待時間是1000毫秒。this
下面是一段JDK中的代碼:spa
/** * Waits at most <code>millis</code> milliseconds for this thread to * die. A timeout of <code>0</code> means to wait forever. */ 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; } } }
從代碼上看,若是線程被生成了,但還未被起動,調用它的 join() 方法是沒有做用的,將直接繼續向下執行線程
Join方法實現是經過wait(小提示:Object 提供的方法)。 當main線程調用t.join時候,main線程會得到線程對象t的鎖(wait 意味着拿到該對象的鎖),調用該對象的wait(等待時間),直到該對象喚醒main線程 ,好比退出後。這就意味着main 線程調用t.join時,必須可以拿到線程t對象的鎖。code
經過下面一段代碼解釋:對象
package ThreadTest; import static java.lang.Thread.currentThread; import static java.lang.Thread.sleep; /** * Created with IntelliJ IDEA. * User: Blank * Date: 14-3-28 * Time: 下午7:49 */ public class TestJoin implements Runnable { public static void main(String[] sure) throws InterruptedException { Thread t = new Thread(new TestJoin()); long start = System.currentTimeMillis(); t.start(); t.join(1000);//等待線程t 1000毫秒 System.out.println(System.currentTimeMillis()-start);//打印出時間間隔 System.out.println("Main finished");//打印主線程結束 } @Override public void run() { // synchronized (currentThread()) { for (int i = 1; i <= 5; i++) { try { sleep(1000);//睡眠5秒,循環是爲了方便輸出信息 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("睡眠" + i); } System.out.println("TestJoin finished");//t線程結束 } //} }
在註釋掉synchronized修飾的run方法後,打印信息以下:blog
能夠看到main線程等待了t線程1000毫秒以後,結束了,隨後是t線程打印的數據。it
那麼若是加上run方法的synchronized那條語句呢?結果以下:io
因爲先調用了t.start()方法,線程進入synchronized代碼段,main線程等待一秒之後,仍是得不到線程t的對象鎖,只能繼續等待,直到線程t結束,釋放鎖。這裏能夠明確看到main線程等待時間是5000ms,有些文章裏寫的是t線程執行時間+join方法指定的時間(5000+1000 ),其實不是的,這裏能夠很清晰的看到,main線程等待時間只有5000ms,看到有的文章說join調用的wait也是須要獲取對象鎖的。
JDK源代碼中wait操做是
public final native void wait(long timeout) throws InterruptedException;
wait內部實現應該是用synchronized,等待時間是5000+1000就好解釋了,搞不明白。
此處存疑。