1. 程式人生 > >深入淺出ReentrantReadWriteLock原始碼解析

深入淺出ReentrantReadWriteLock原始碼解析

> 讀寫鎖實現邏輯相對比較複雜,但是卻是一個經常使用到的功能,希望將我對`ReentrantReadWriteLock`的原始碼的理解記錄下來,可以對大家有幫助 ## 前提條件 在理解`ReentrantReadWriteLock`時需要具備一些基本的知識 ### 理解AQS的實現原理 之前有寫過一篇[《深入淺出AQS原始碼解析》](https://www.cnblogs.com/pinxiong/p/13288201.html)關於AQS的文章,對AQS原理不瞭解的同學可以先看一下 ### 理解ReentrantLock的實現原理 `ReentrantLock`的實現原理可以參考[《深入淺出ReentrantLock原始碼解析》](https://www.cnblogs.com/pinxiong/p/13304210.html) ### 什麼是讀鎖和寫鎖 對於資源的訪問就兩種形式:要麼是讀操作,要麼是寫操作。讀寫鎖是將被鎖保護的臨界資源的讀操作和寫操作分開,允許同時有多個執行緒同時對臨界資源進行讀操作,任意時刻只允許一個執行緒對資源進行寫操作。簡單的說,對與讀操作採用的是**共享鎖**,對於寫操作採用的是**排他鎖**。 ### 讀寫狀態的設計 `ReentrantReadWriteLock`是用`state`欄位來表示讀寫鎖重複獲取資源的次數,高16位用來標記讀鎖的同步狀態,低16位用來標記寫鎖的同步狀態 ``` // 劃分的邊界線,用16位來劃分 static final int SHARED_SHIFT = 16; // 讀鎖的基本單位,也就是讀鎖加1或者減1的基本單位(1左移16位後的值) static final int SHARED_UNIT = (1 << SHARED_SHIFT); // 讀寫鎖的最大值(在計算讀鎖的時候需要先右移16位) static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; // 寫鎖的掩碼,state值與掩碼做與運算後得到寫鎖的真實值 static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; // 獲取資源被讀鎖佔用的次數 static int sharedCount(int c){ return c >>> SHARED_SHIFT; } // 獲取資源被寫鎖佔用的次數 static int exclusiveCount(int c){ return c & EXCLUSIVE_MASK; } ``` 在統計讀鎖被每個執行緒持有的次數時,`ReentrantReadWriteLock`採用的是`HoldCounter`來實現的,具體如下: ``` // 持有讀鎖的執行緒重入的次數 static final class HoldCounter { // 重入的次數 int count = 0; // 持有讀鎖執行緒的執行緒id final long tid = getThreadId(Thread.currentThread()); } /** * 採用ThreadLocal機制,做到執行緒之間的隔離 */ static final class ThreadLocalHoldCounter extends Thr