您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java條件隊(duì)列是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java條件隊(duì)列是什么”吧!
關(guān)于條件隊(duì)列,你能說些什么?
條件隊(duì)列是一個(gè)容器,它承載著一組等待“先驗(yàn)條件”成真的線程。
先驗(yàn)條件這個(gè)詞文縐縐的,用白話講就是你做一件事的前提條件。在代碼里經(jīng)常表現(xiàn)為你調(diào)用的方法能夠執(zhí)行的前提條件。舉個(gè)例子,對(duì)于BlockingQueue你要調(diào)用put()方法,那么這個(gè)put方法能被成功調(diào)用的前提是這個(gè)blockingQueue不滿。對(duì)于已滿的情況,在同步的世界里,你可以拋異常、你可以返回一個(gè)特殊的自定義的值(在函數(shù)式編程里你可以做得更好)。在并發(fā)的世界里,如果能夠block住并等到隊(duì)列不滿的時(shí)候再繼續(xù)執(zhí)行是更好的設(shè)計(jì)。“條件隊(duì)列”就是用于這種“等待、通知、再運(yùn)行”機(jī)制里的一個(gè)關(guān)鍵組件。
上面提到等待、通知時(shí),你是不是馬上想到了耳熟能詳?shù)膕ychronized關(guān)鍵字?因?yàn)樵趕ynchronized里,我們經(jīng)常使用wati(), notify(), notifyAll()嘛。如果你直接想到object那也挺厲害的。
先驗(yàn)條件往往與對(duì)象的狀態(tài)關(guān)聯(lián)在一起,因?yàn)轶w現(xiàn)到代碼上這些條件最終都是基于某些“對(duì)象屬性”進(jìn)行的布爾運(yùn)算的結(jié)果,用這個(gè)結(jié)果來決定個(gè)先驗(yàn)條件是否成立。在并發(fā)的世界里,對(duì)這些對(duì)象屬性必須同步才能避免多線程下因競(jìng)爭(zhēng)而導(dǎo)致的問題,這就需要一個(gè)鎖把這些先驗(yàn)條件用到的狀態(tài)同步起來,所以就有了下面這樣的邏輯:先驗(yàn)條件 --> 狀態(tài) --> 鎖。為了檢驗(yàn)一個(gè)條件,我們必須先持有鎖。
回到上面blockingQueue的例子,我們先拿到這個(gè)隊(duì)列的鎖、再檢查隊(duì)列是否已滿。如果隊(duì)列已滿,我們就不能繼續(xù)執(zhí)行put,需要block住,然后等候隊(duì)列不滿的通知。如何實(shí)現(xiàn)呢?調(diào)用wait()釋放鎖,等候條件成真后的通知notify,然后再繼續(xù)執(zhí)行。有可能得到條件變化為真的通知,但是拿到cpu時(shí)間槽要執(zhí)行的時(shí)候,條件又false了,所以wait要寫在while里,這算是個(gè)定式。
其實(shí),講到這里后面已經(jīng)默默的使用到了condition queue。當(dāng)你調(diào)用wait的時(shí)候,這個(gè)線程就進(jìn)到了條件隊(duì)列。而當(dāng)有其它線程notify的時(shí)候,實(shí)際上就是通知條件隊(duì)列里的線程(先驗(yàn))條件發(fā)生了變化,讓這些線程有機(jī)會(huì)重新去檢查這些條件并繼續(xù)運(yùn)行。在這里,我們可以體會(huì)下調(diào)用wait()都隱式的對(duì)應(yīng)到等待一個(gè)先驗(yàn)條件(條件謂詞)為真,而調(diào)用notify/All都隱式的對(duì)應(yīng)到一個(gè)先驗(yàn)條件發(fā)生了變化。
大家一般都知道sycnhronized與monitor(內(nèi)置鎖)緊密聯(lián)系。進(jìn)入同步代碼塊之前,你必須擁有monitor。實(shí)際上,條件隊(duì)列也是與鎖緊密聯(lián)系的(甚至就是‘同一個(gè)’對(duì)象)。就內(nèi)置條件隊(duì)列來說,比較不好的一面是:調(diào)用wait()把線程放入這個(gè)內(nèi)部條件隊(duì)列意味著因?yàn)榈却煌跋闰?yàn)條件”的線程都在同一隊(duì)列中,就是說不同的先驗(yàn)條件共享同一個(gè)內(nèi)部條件隊(duì)列。這樣在notifyAll進(jìn)行喚醒的時(shí)候就并不高效了。
而Condition接口,可以幫助我們針對(duì)不同的先驗(yàn)條件創(chuàng)建不同的條件隊(duì)列,這樣就可以只喚醒與之對(duì)應(yīng)的線程了。從鎖與條件隊(duì)列的關(guān)系你應(yīng)該可以猜到,Lock接口提供了創(chuàng)建條件隊(duì)列的方法。
public interface Lock { Condition newCondition(); ... ...
下面是Condition的接口定義,可以看到就如Lock是內(nèi)部鎖的泛化、顯示化,而Condition就是內(nèi)部條件隊(duì)列的泛化、顯示化。
感謝各位的閱讀,以上就是“Java條件隊(duì)列是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Java條件隊(duì)列是什么這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。