摘要:造成當前線程在接到信號被中斷或到達指定最后期限之前一直處于等待狀態。我們喜歡在多帶帶的等待中保存線程和線程,這樣就可以在緩沖區中的項或空間變得可用時利用最佳規劃,一次只通知一個線程。
Condition接口
Condition的功能類似于傳統線程技術中的Object.wait()和Object.notify()方法的功能,但它是將這些方法分解成不同的對象,所以可以將這些對象與任意的Lock實現組合使用,實現在不同的條件下阻塞或喚醒線程;也就是說,這其中的Lock替代了synchronized方法和語句的使用,Condition替代了Object 監視器方法(wait、notify 和 notifyAll)的使用。創建一個Condition
Condition需要被綁定在一個鎖(Lock)上,所以如果要為一個Lock實例獲得Condition實例,可以使用Lock的newCondition() 方法。
Condition notFull = lock.newCondition();Condition接口的常用方法
void await()代碼示例
造成當前線程在接到信號或被中斷之前一直處于等待狀態。
boolean await(long time, TimeUnit unit)
造成當前線程在接到信號、被中斷或到達指定等待時間之前一直處于等待狀態。
long awaitNanos(long nanosTimeout)
造成當前線程在接到信號、被中斷或到達指定等待時間之前一直處于等待狀態。
void awaitUninterruptibly()
造成當前線程在接到信號之前一直處于等待狀態。
boolean awaitUntil(Date deadline)
造成當前線程在接到信號、被中斷或到達指定最后期限之前一直處于等待狀態。
void signal()
喚醒一個等待線程。
void signalAll()
喚醒所有等待線程。
這段代碼是JDK API文檔中提供的示例,假定有一個綁定的緩沖區,它支持 put 和 take 方法。如果試圖在空的緩沖區上執行 take 操作,則在某一個項變得可用之前,線程將一直阻塞;如果試圖在滿的緩沖區上執行 put 操作,則在有空間變得可用之前,線程將一直阻塞。我們喜歡在多帶帶的等待 set 中保存 put 線程和 take 線程,這樣就可以在緩沖區中的項或空間變得可用時利用最佳規劃,一次只通知一個線程。可以使用兩個 Condition 實例來做到這一點。
public class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) { //當緩沖區已滿時,notFull阻塞 notFull.await(); } //否則將元素添加進緩沖區的下標位置 items[putptr] = x; if (++putptr == items.length) { //如果下一個下標越界,則將下標移至緩沖區首位 putptr = 0; } //count表示緩沖區中元素個數 ++count; //由于緩沖已經是notEmpty狀態,所以喚醒阻塞等待的notEmpty notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) { //當緩沖區中沒有元素,緩沖區處于empty狀態,所以notEmpty阻塞 notEmpty.await(); } Object x = items[takeptr]; if (++takeptr == items.length) { //獲得下標位置的元素后,將下標向前移動,如果移動后的下標越界,則將下標移至緩沖區首位 takeptr = 0; } --count; //取出一個元素后,緩沖區處于notFull狀態,所以喚醒阻塞等待的notFull notFull.signal(); return x; } finally { lock.unlock(); } } }注意:
和監視器方法一樣,Condition也可能發生“虛假喚醒”,所以Condition必須在總是在一個循環中被等待,并在被喚醒后測試當前狀態,判斷當前是否已經處于可以被喚醒的狀態,我們需要假定“虛假喚醒”可能發生。
while (count == 0) { //在循環中等待 condition.await(); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68809.html
摘要:提供了多線程升級方案將同步替換成了顯示的操作。線程間通信接口可以替代傳統的線程間通信,用替換,用替換,用替換。商品執行上述代碼,觀察結果可以看到,多個線程同時生產消費,由于指定喚醒互異線程,因此并不會引起錯誤。 JDK 1.5提供了多線程升級方案將同步synchronized替換成了顯示的Lock操作。可以實現喚醒、凍結指定的線程。 Lock接口Lock 實現提供了比使用 synchr...
摘要:本文對多線程基礎知識進行梳理,主要包括多線程的基本使用,對象及變量的并發訪問,線程間通信,的使用,定時器,單例模式,以及線程狀態與線程組。源碼采用構建,多線程這部分源碼位于模塊中。通知可能等待該對象的對象鎖的其他線程。 本文對多線程基礎知識進行梳理,主要包括多線程的基本使用,對象及變量的并發訪問,線程間通信,lock的使用,定時器,單例模式,以及線程狀態與線程組。 寫在前面 花了一周時...
摘要:二接口簡介可以看做是類的方法的替代品,與配合使用。當線程執行對象的方法時,當前線程會立即釋放鎖,并進入對象的等待區,等待其它線程喚醒或中斷。 showImg(https://segmentfault.com/img/remote/1460000016012601); 本文首發于一世流云的專欄:https://segmentfault.com/blog... 本系列文章中所說的juc-...
摘要:無論是互斥鎖,還是自旋鎖,在任何時刻,最多只能有一個保持者,也就說,在任何時刻最多只能有一個執行單元獲得鎖。另外在中引入了自適應的自旋鎖。和關鍵字的總結推薦一 該文已加入開源文檔:JavaGuide(一份涵蓋大部分Java程序員所需要掌握的核心知識)。地址:https://github.com/Snailclimb... 本文是對 synchronized 關鍵字使用、底層原理、JD...
閱讀 2074·2021-10-11 10:59
閱讀 933·2021-09-23 11:21
閱讀 3560·2021-09-06 15:02
閱讀 1619·2021-08-19 10:25
閱讀 3374·2021-07-30 11:59
閱讀 2370·2019-08-30 11:27
閱讀 2583·2019-08-30 11:20
閱讀 2976·2019-08-29 13:15