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