Join 讓執行這個方法的線程插隊 ,讓當前縣城執行完再執行別的線程
java
package org.famous.unyielding.current.jooin; public class ThreadJoinClient { public static void main(String[] args) { Thread t = new Thread(new Runnable() { @Override public void run() { System.err.println("Hello World"); } }); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } t.start(); System.err.println("main thread"); } }
加Join 和不加Join的結果就是hello World 輸出的順序不一致。加了Join那麼Hello World 會優先執行dom
Join(Long xx) Sleep(Long xx)的區別 。Join會釋放鎖,可是Sleep不會ide
首先驗證Join(Long xx)的方法 第二證實Join鎖機制:ui
package org.famous.unyielding.current.jooin; public class ThreadJoinClient { public static void main(String[] args) { Thread t = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("Hello World"); } }); t.start(); try { t.join(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("main thread"); } }
必須先Start再Join 不然無效。!這點詳細見join的源碼:this
if (millis == 0) { spa
while (isAlive()) { 線程
wait(0); code
} ci
} else { rem
join的鎖機制:
上面的代碼中得看是誰調用了join 是主線程 因此中止的是主線程。
本質問題:join(1000)和sleep(1000)的區別是什麼。讓子線程Join 或者讓主線程sleep 本質上均可以達到咱們的要求。只要咱們預估好時間。
可是若是不加時間呢。仍是爲了驗證鎖的問題。
就是join 會不會讓調用它的線程釋放鎖。
1.join 的參數並非一直等待到指定的時間,若是線程提早運行完成以後仍是會提早結束等待的
2.
public class MyTest { public static void main(String[] args) { SonRun sonRun = new SonRun(); Thread thread = new Thread(new JoinRunn(sonRun)); thread.start(); Thread thread2 = new Thread(new ThreeRrun(sonRun)); thread2.start(); } } // 我調用join 會釋放鎖嗎 class JoinRunn implements Runnable { private SonRun sonrun; public JoinRunn(SonRun sonrun) { super(); this.sonrun = sonrun; } @Override public void run() { synchronized (sonrun) { System.err.println("join run get the sonrun lock"); try { sonrun.start(); /*** zhongdian **/ // sonrun.join(3000); Thread.sleep(3000); System.err.println("join run will execute after SonRun"); for (int i = 0; i < Integer.MAX_VALUE; i++) { String newString = new String(); Math.random(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } class SonRun extends Thread { @Override public void run() { Long begin = System.currentTimeMillis(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } Long end = System.currentTimeMillis(); System.err.println(begin - end); } } class ThreeRrun implements Runnable { private SonRun sonrun; public ThreeRrun(SonRun sonrun) { this.sonrun = sonrun; } @Override public void run() { synchronized (sonrun) { System.err.println("what the time shold i fucked be execute"); } } }
這個代碼的運行結果在JoinRunn的
// sonrun.join(3000);
Thread.sleep(3000);
分別運行結果是不一樣的。因此得警戒Join 是會釋放鎖這個問題的。
join()
If any executing thread t1 calls join()
on t2 i.e; t2.join()
immediately t1 will enter into waiting state until t2 completes its execution. t1調用了t2的join方法,那麼t1就會先wait 直到時間結束或者t1運行結束。既然是wait,那麼同步的或者加鎖的到底是哪一個地方??
yield()
join()
sleep()
yield()
method pauses the currently executing thread temporarily for giving a chance to the remaining waiting threads of the same priority to execute. If there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue its execution. The yielded thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor dependent.
sleep()
Based on our requirement we can make a thread to be in sleeping state for a specified period of time (hope not much explanation required for our favorite method).
下面關於Yield的
package org.famous.unyielding.current.jooin; public class YieldThreadClient { public static void main(String[] args) { Thread thread1 = new Thread(new YieldRunn()); Thread thread2 = new Thread(new YieldRunn()); thread1.start(); thread2.start(); } } class YieldRunn implements Runnable { @Override public void run() { for (int i = 0; i < 130; i++) { System.err.println(i); if (i == 30) { Thread.yield(); } } } }