Java中join()方法的理解


thread.Join把指定的線程加入到當前線程,可以將兩個交替執行的線程合並為順序執行的線程。

比如在線程B中調用了線程A的Join()方法,直到線程A執行完畢后,才會繼續執行線程B。

t.join();      //調用join方法,等待線程t執行完畢
t.join(1000);  //等待 t 線程,等待時間是1000毫秒。

下面是一段JDK中的代碼:

復制代碼
    /** * 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對象的鎖。

通過下面一段代碼解釋:

復制代碼
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方法后,打印信息如下:

 

可以看到main線程等待了t線程1000毫秒之后,結束了,隨后是t線程打印的數據。

那么如果加上run方法的synchronized那條語句呢?結果如下:

由於先調用了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就好解釋了,搞不明白。

此處存疑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM