在 ArrayBlockingQueue 的源碼中, 可以看到兩個Condition對象
ReentrantLock lock = new ReentrantLock(fair);
Condition notEmpty = lock.newCondition();
Condition notFull = lock.newCondition();
這兩個condition是做什麼的呢?
總結
看下源碼, lock.newCondition()
是 Lock 接口中定義的方法, 在 ReentrantLock 的實現中 return AbstractQueuedSynchronizer.newCondition()
, 而這個 AbstractQueuedSynchronizer.newCondition()
創建了 AbstractQueuedSynchronizer 的內部類 public class ConditionObject implements Condition, java.io.Serializable
.
下面看見 ConditionObject 的類結構
總的來說, Lock + Condition ≈ Synchronized + Object.wait()/notify()
Condition中的await()方法相當於Object的wait()方法,Condition中的signal()方法相當於Object的notify()方法,Condition中的signalAll()相當於Object的notifyAll()方法.
不同的是, 同一個鎖可以有多個 Condition, 提供多種情況的互不干擾的控制.
內部實現
ConditionObject 中使用Node類實現了一個鏈表, 用來緩存所有的等待線程.
- 每次執行await()等待時, 都會在addConditionWaiter()方法裏使用當前await()所在的線程構建一個node對象, 並插入到等待鏈表中;
- 執行signal()時又會在transferForSignal()方法中從鏈表中移除頂部node, 並把該node內的thread從阻塞隊列中轉移到可運行隊列中.