您好,登錄后才能下訂單哦!
這篇文章主要介紹了Java四個線程常用函數是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
使當前線程等待,直到它被喚醒,通常是通過被通知或被中斷,或者直到經過一定的實時時間。
本身屬于一個Object 類,查看源代碼也可知:public class Object {
查看其源碼可知,一共有三個重載的方法,詳情源代碼如下:
//第一個重載函數 public final void wait() throws InterruptedException { wait(0L); } //第二個重載函數 public final native void wait(long timeoutMillis) throws InterruptedException; //第三個重載函數 public final void wait(long timeoutMillis, int nanos) throws InterruptedException { if (timeoutMillis < 0) { throw new IllegalArgumentException("timeoutMillis value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) { timeoutMillis++; } wait(timeoutMillis); }
具體實戰調用代碼如下:
如果執行到了wait函數,在這4秒內,會釋放鎖,并且暫停線程。如果這四秒內配合notify()可以喚醒并且得到鎖,如果沒有喚醒,等待其他來競爭。4秒結束后,會默認自動釋放鎖
當前線程在 Thread.wait()等待過程中,如果Thread結束了,是可以自動喚醒的而且自動釋放鎖
@Override public void run() { synchronized (a) { a.wait(4000); } }
join是Thread類的方法
查看其源碼,具體源碼如下,三個重載的方法
//第一個重載函數 public final synchronized void join(final long millis) throws InterruptedException { if (millis > 0) { if (isAlive()) { final long startTime = System.nanoTime(); long delay = millis; do { wait(delay); } while (isAlive() && (delay = millis - TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0); } } else if (millis == 0) { while (isAlive()) { wait(0); } } else { throw new IllegalArgumentException("timeout value is negative"); } } //第二個重載函數 /*等待該線程死亡的時間最多為毫秒加納秒。 如果兩個參數都為0,則意味著永遠等待。 這個實現使用了This的循環。 等待電話以this.isAlive為條件。 當一個線程終止this。 調用notifyAll方法。 建議應用程序不要使用wait、notify或notifyAll on Thread實例。 */ public final synchronized void join(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0 && millis < Long.MAX_VALUE) { millis++; } join(millis); } //第三個重載函數 /*等待線程死亡。 此方法的調用與調用的行為完全相同 InterruptedException—如果任何線程中斷了當前線程。 當拋出此異常時,當前線程的中斷狀態將被清除。 */ public final void join() throws InterruptedException { join(0); }
主要的時間參數邏輯如下:
小于0,拋出異常
等于0,join(A),判斷A是否存在,存在才執行操作。該線程執行wait(0)等待,等待A線程執行完后才可結束
大于0,同上,只不過執行的是wait(long millis),等待時間結束后才可繼續執行操作
對比上一個wait函數
sleep(long mills):讓出CPU資源,但是不會釋放鎖資源。
wait():讓出CPU資源和鎖資源。
查看sleep函數的源碼,一共有兩個重載函數
都是Thread類的函數
/*根據系統計時器和調度器的精度和準確性, 使當前執行的線程在指定的毫秒數內處于睡眠狀態(暫時停止執行)。 線程不會失去任何監視器的所有權。*/ public static native void sleep(long millis) throws InterruptedException; /*導致當前執行的線程在指定的毫秒數加上指定的納秒數 (取決于系統計時器和調度器的精度和準確性)內休眠(暫時停止執行)。 線程不會失去任何監視器的所有權。 */ public static void sleep(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0 && millis < Long.MAX_VALUE) { millis++; } sleep(millis); }
查看yield()函數的源碼,一個重載函數
都是Thread類的函數
向調度器暗示當前線程愿意放棄當前對處理器的使用。 調度器可以忽略這個提示。
Yield是一種啟發式嘗試,旨在改善線程之間的相對進程,否則會過度使用CPU。 它的使用應該與詳細的分析和基準測試相結合,以確保它實際上具有預期的效果。
使用這種方法很少是合適的。 它可能用于調試或測試目的,在這些目的中,它可能有助于由于競爭條件而重新生成錯誤。 在設計并發控制構造(如java.util.concurrent.locks包中的構造)時,它可能也很有用。
public static native void yield();
總的來說,yield函數的功能主要是:
讓出CPU調度,暫停線程,但不能由用戶指定時間
只能讓同優先級有執行機會
wait 暫停該線程,讓出cpu,釋放鎖。(Object類)
join暫停該線程,執行該線程之后才能回到自身的線程運行。(Thread類)
sleep 暫停該線程,讓出cpu,不釋放鎖。(Thread類)
yield 暫停該線程,但是不能由用戶制定,只能讓同優先級有執行機會。(Thread類)
看完以上的源碼以及邏輯代碼,再講講兩者的異同
總的來說
wait函數:讓當前線程進入等待狀態,wait()會與notify()和notifyAll()方法一起使用。notify為喚醒函數
join函數:等待這個線程結束才能執行自已的線程。它的主要起同步作用,使線程之間的執行從“并行”變成“串行”。線程A中調用了線程B的join()方法時,線程
執行過程發生改變:線程A,必須等待線程B執行完畢后,才可以繼續執行下去
共同點:
暫停當前的線程
都可以通過中斷喚醒
不同點在于:
區別 | wait | join |
---|---|---|
類 | Object類 | Thread類 |
目的 | 線程間通信 | 排序,讓其串行通過 |
同步 | 必須要synchronized | 可以不用synchronized |
wait():讓出CPU資源和鎖資源。
sleep(long mills):讓出CPU資源,但是不會釋放鎖資源。
看區別,主要是看CPU的運行機制:
它們的區別主要考慮兩點:1.cpu是否繼續執行、2.鎖是否釋放掉。
歸根到底:
wait,notify,notifyall 都是Object對象的方法,是一起使用的,用于鎖機制,所以會釋放鎖
而sleep是Thread類,跟鎖沒關系,不會釋放鎖
但是兩者都會讓出cpu資源
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Java四個線程常用函數是什么”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。