ReentrantReadWriteLock
類, 顧名思義, 是一種讀寫鎖, 它是 ReadWriteLock
接口的直接實現, 該類在內部實現了具體獨佔鎖特色的寫鎖, 以及具備共享鎖特色的讀鎖, 和 ReentrantLock
同樣, ReentrantReadWriteLock
類也是經過定義內部類實現AQS框架的API來實現獨佔/共享的功能.java
ReentrantLock
屬於排他鎖, 這些鎖在同一時刻只容許一個線程進行訪問, 可是在大多數場景下, 大部分時間都是提供讀服務, 而寫服務佔有的時間較少. 並且, 讀服務不存在數據競爭問題, 若是一個線程在讀時禁止其餘線程讀勢必會致使性能下降. 因此就提供了讀寫鎖.併發
讀寫鎖維護着一對鎖, 一個讀鎖和一個寫鎖. 經過分離讀鎖和寫鎖, 使得併發性比通常的排他鎖有了較大的提高:框架
讀寫鎖的主要特性:ide
讀寫鎖 ReentrantReadWriteLock
實現接口 ReadWriteLock
, 該接口維護了一對相關的鎖, 一個用於只讀操做, 另外一個用於寫入操做. 只要沒有 writer
, 讀取鎖能夠由多個 reader
線程同時保持. 寫入鎖是獨佔的.性能
public interface ReadWriteLock { Lock readLock(); Lock writeLock(); }
ReadWriteLock
定義了兩個方法. readLock()
返回用於讀操做的鎖, writeLock()
返回用於寫操做的鎖.this
java.util.concurrent.locks.ReentrantReadWriteLock
定義以下.線程
/** 內部類 讀鎖 */ private final ReentrantReadWriteLock.ReadLock readerLock; /** 內部類 寫鎖 */ private final ReentrantReadWriteLock.WriteLock writerLock; final Sync sync; /** 使用默認(非公平)的排序屬性建立一個新的 ReentrantReadWriteLock */ public ReentrantReadWriteLock() { this(false); } /** 使用給定的公平策略建立一個新的 ReentrantReadWriteLock */ public ReentrantReadWriteLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new WriteLock(this); } /** 返回用於寫入操做的鎖 */ @Override public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } /** 返回用於讀取操做的鎖 */ @Override public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } abstract static class Sync extends AbstractQueuedSynchronizer { /** * 省略其他源代碼 */ } public static class WriteLock implements Lock, java.io.Serializable { /** * 省略其他源代碼 */ } public static class ReadLock implements Lock, java.io.Serializable { /** * 省略其他源代碼 */ }
ReentrantReadWriteLock
與 ReentrantLock
同樣, 其鎖主體依然是 Sync, 它的讀鎖、寫鎖都是依靠 Sync 來實現的.code
因此 ReentrantReadWriteLock
實際上只有一個鎖, 只是在獲取讀取鎖和寫入鎖的方式上不同而已, 它的讀寫鎖其實就是兩個類: ReadLock
、writeLock
, 這兩個類都是lock實現.排序
在 ReentrantLock
中, 使用 Sync ( 實際是 AQS ) 的 int
類型的 state
來表示同步狀態, 表示鎖被一個線程重複獲取的次數. 遞歸
可是, 讀寫鎖 ReentrantReadWriteLock
內部維護着一對讀寫鎖, 若是要用一個變量維護多種狀態, 須要採用 「按位切割使用」 的方式來維護這個變量, 將其切分爲兩部分: 高16爲表示讀, 低16爲表示寫.