1. 程式人生 > >ReentrantReadWriteLock可重入讀寫鎖使用

ReentrantReadWriteLock可重入讀寫鎖使用

特點

可重入:就是同一個執行緒可以重複加鎖,可以對同一個鎖加多次,每次釋放的時候回釋放一次,直到該執行緒加鎖次數為0,這個執行緒才釋放鎖。比如同一個執行緒中可以對同一個鎖加多次寫入鎖。寫執行緒獲取寫入鎖後可以再次獲取讀取鎖,但是讀執行緒獲取讀取鎖後卻不能獲取寫入鎖。
讀寫鎖: 也就是讀鎖可以共享,多個執行緒可以同時擁有讀鎖,但是寫鎖卻只能只有一個執行緒擁有,而且獲取寫鎖的時候,其他執行緒都已經釋放了讀鎖,而且在該執行緒獲取寫鎖之後,其他執行緒不能再獲取讀鎖。
鎖降級:寫執行緒獲取寫入鎖後可以獲取讀取鎖,然後釋放寫入鎖,這樣就從寫入鎖變成了讀取鎖,從而實現鎖降級的特性。
鎖升級:讀取鎖是不能直接升級為寫入鎖的。因為獲取一個寫入鎖需要釋放所有讀取鎖,所以如果有兩個讀取鎖試圖獲取寫入鎖而都不釋放讀取鎖時就會發生死鎖。
重入數:讀取鎖和寫入鎖的數量最大分別只能是65535(包括重入數)
鎖獲取中斷:讀取鎖和寫入鎖都支援獲取鎖期間被中斷。這個和獨佔鎖一致。

示例

下面是原始碼中提供的示例:

 * class CachedData {
 *   Object data;
 *   volatile boolean cacheValid;
 *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
 *
 *   void processCachedData() {
 *     rwl.readLock().lock();
 *     if (!cacheValid) {
 *       // Must release read lock before acquiring write
lock * rwl.readLock().unlock();
* rwl.writeLock().lock(); * try { * // Recheck state because another thread might have * // acquired write lock and changed state before we did. * if (!cacheValid) { * data = ... * cacheValid = true; * } * // Downgrade by acquiring read lock
before releasing write lock * rwl.readLock().lock();
* } finally { * rwl.writeLock().unlock(); // Unlock write, still hold read * } * } * * try { * use(data); * } finally { * rwl.readLock().unlock(); * } * } * }
 * class RWDictionary {
 *   private final Map<String, Data> m = new TreeMap<String, Data>();
 *   private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
 *   private final Lock r = rwl.readLock();
 *   private final Lock w = rwl.writeLock();
 *
 *   public Data get(String key) {
 *     r.lock();
 *     try { return m.get(key); }
 *     finally { r.unlock(); }
 *   }
 *   public String[] allKeys() {
 *     r.lock();
 *     try { return m.keySet().toArray(); }
 *     finally { r.unlock(); }
 *   }
 *   public Data put(String key, Data value) {
 *     w.lock();
 *     try { return m.put(key, value); }
 *     finally { w.unlock(); }
 *   }
 *   public void clear() {
 *     w.lock();
 *     try { m.clear(); }
 *     finally { w.unlock(); }
 *   }
 * }