今天我們來學習一下Condition(身份)Condition是在Java 1.5中才出現的,它用來替代傳統的Object的wait()、notify()實現線程間的協作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()這種方式實現線程間協作更加安全和高效。
它的更強大的地方在於:能夠更加精細的控制多線程的休眠與喚醒。對於同一個鎖,我們可以創建多個Condition,在不同的情況下使用不同的Condition 。一個Condition包含一個等待隊列。一個Lock可以產生多個Condition,所以可以有多個等待隊列。
在Object的監視器模型上,一個對象擁有一個同步隊列和等待隊列,而Lock(同步器)擁有一個同步隊列和多個等待隊列。
Object中的wait(),notify(),notifyAll()方法是和"同步鎖"(synchronized關鍵字)捆綁使用的;而Condition是需要與"互斥鎖"/"共享鎖"捆綁使用的。
調用Condition的await()、signal()、signalAll()方法,都必須在lock保護之內,就是說必須在lock.lock()和lock.unlock之間纔可以使用
- Conditon中的await()對應Object的wait();
- Condition中的signal()對應Object的notify();
- Condition中的signalAll()對應Object的notifyAll()。
- await()
- void await() throws InterruptedException
造成當前線程在接到信號或被中斷之前一直處於等待狀態。
與此 Condition 相關的鎖以原子方式釋放,並且出於線程調度的目的,將禁用當前線程,且在發生以下四種情況之一 以前,當前線程將一直處於休眠狀態:- 其他某個線程調用此 Condition 的 signal() 方法,並且碰巧將當前線程選爲被喚醒的線程;或者
- 其他某個線程調用此 Condition 的 signalAll() 方法;或者
- 其他某個線程中斷當前線程,且支持中斷線程的掛起;或者
- 發生“虛假喚醒”
在所有情況下,在此方法可以返回當前線程之前,都必須重新獲取與此條件有關的鎖。在線程返回時,可以保證它保持此鎖。
-
void signal()
喚醒一個等待線程。
如果所有的線程都在等待此條件,則選擇其中的一個喚醒。在從 await 返回之前,該線程必須重新獲取鎖。 -
void signalAll()
喚醒所有等待線程。
如果所有的線程都在等待此條件,則喚醒所有線程。在從 await 返回之前,每個線程都必須重新獲取鎖。