Java Condition條件變量提高線程通信效率
條件(也稱為條件隊列 或條件變量)為線程提供了一個含義,以便在某個狀態(tài)條件現(xiàn)在可能為 true 的另一個線程通知它之前,一直掛起該線程(即讓其“等待”)。因為訪問此共享狀態(tài)信息發(fā)生在不同的線程中,所以它必須受保護,因此要將某種形式的鎖與該條件相關(guān)聯(lián)。等待提供一個條件的主要屬性是:以原子方式 釋放相關(guān)的鎖,并掛起當前線程,就像 Object.wait 做的那樣
在Condition中,用await()替換wait(),用signal()替換notify(),用signalAll()替換notifyAll(),傳統(tǒng)線程的通信方式,Condition都可以實現(xiàn)。
條件變量類似JDK1.4或以前版本中的 Object.wait(); Object.notify(); Object.notifyAll();
值得注意的是當condition.await()時,隱式的將條件變量關(guān)聯(lián)的Lock解鎖,而使其他線程有機會獲得Lock,而檢查條件,并在條件滿足時,等待在條件變量上。
示例代碼,ArrayBlockingQueue源碼摘取:
/** Main lock guarding all access */private final ReentrantLock lock;/** Condition for waiting takes */private final Condition notEmpty;/** Condition for waiting puts */private final Condition notFull;/** * Inserts the specified element at the tail of this queue, waiting * for space to become available if the queue is full. * * @throws InterruptedException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); final E[] items = this.items; final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { try { while (count == items.length) notFull.await(); } catch (InterruptedException ie) { notFull.signal(); // propagate to non-interrupted thread throw ie; } insert(e); } finally { lock.unlock(); }}public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { try { while (count == 0) notEmpty.await(); } catch (InterruptedException ie) { notEmpty.signal(); // propagate to non-interrupted thread throw ie; } E x = extract(); return x; } finally { lock.unlock(); }}
有多個線程往里面存數(shù)據(jù)和從里面取數(shù)據(jù),其隊列(先進先出后進后出)能緩存的最大數(shù)值是capacity,多個線程間是互斥的,當緩存隊列中存儲的值達到capacity時,將寫線程阻塞,并喚醒讀線程,當緩存隊列中存儲的值為0時,將讀線程阻塞,并喚醒寫線程這就是多個Condition的強大之處,假設(shè)緩存隊列中已經(jīng)存滿,那么阻塞的肯定是寫線程,喚醒的肯定是讀線程,相反,阻塞的肯定是讀線程,喚醒的肯定是寫線程,那么假設(shè)只有一個Condition會有什么效果呢,緩存隊列中已經(jīng)存滿,這個Lock不知道喚醒的是讀線程還是寫線程了,如果喚醒的是讀線程,皆大歡喜,如果喚醒的是寫線程,那么線程剛被喚醒,又被阻塞了,這時又去喚醒,這樣就浪費了很多時間!
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. Docker究竟是什么 為什么這么流行 它的優(yōu)點和缺陷有哪些?2. ASP.NET MVC實現(xiàn)城市或車型三級聯(lián)動3. JS中的常見數(shù)組遍歷案例詳解(forEach, map, filter, sort, reduce, every)4. Java 批量獲取地址間距離工具(支持中轉(zhuǎn)站)5. python如何用matplotlib創(chuàng)建三維圖表6. Python使用Pyqt5實現(xiàn)簡易瀏覽器(最新版本測試過)7. Element ui tree(樹)實現(xiàn)父節(jié)點選中時子節(jié)點不選中父節(jié)點取消時子節(jié)點自動取消功能8. 如何在.net6webapi中使用自動依賴注入9. ASP中格式化時間短日期補0變兩位長日期的方法10. java實現(xiàn)彈球小游戲
