protected final boolean tryAcquire(int acquires) { Thread current = Thread.currentThread();monitor int c = getState(); // 重入鎖的計數 int w = exclusiveCount(c); // 計數高低位拆開爲讀計數跟寫計數,計算寫計數 if (c != 0) { // 有人在佔有鎖 if (w == 0 || current != getExclusiveOwnerThread()) // 寫計數爲0,只有讀鎖直接返回(避免了讀鎖升級爲寫鎖) 或者 當前線程不是執行線程(執行線程可能讀也可能寫)也返回 return false; if (w + exclusiveCount(acquires) > MAX_COUNT) //寫鎖重入次數 > 65525,拋出異常 throw new Error("Maximum lock count exceeded"); setState(c + acquires); //重入的寫線程,直接設置狀態(第6行代碼沒有return,說明當前線程是重入的寫線程(寫計數不是0,且current就是獲取鎖的線程)) return true; } if (writerShouldBlock() || !compareAndSetState(c, c + acquires)) //c!=0沒有return,說明當前鎖是空着的,因此cas搶佔 return false; setExclusiveOwnerThread(current); // 當前線程參數設置 return true; }
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) //沒有獲取到,就往等待隊列添加節點,而後掛起線程 selfInterrupt(); }
protected final boolean tryRelease(int releases) { if (!isHeldExclusively()) //沒有寫鎖,拋異常 throw new IllegalMonitorStateException(); int nextc = getState() - releases; boolean free = exclusiveCount(nextc) == 0; //次數是否清0了 if (free) //清0 了,說明徹底釋放了 setExclusiveOwnerThread(null); setState(nextc); return free; }
protected final int tryAcquireShared(int unused) { Thread current = Thread.currentThread(); int c = getState(); if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) // 有寫鎖 且當前線程不是寫鎖線程,不能重入,失敗 return -1; int r = sharedCount(c); //向右移位,獲取讀鎖計數 if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { // 若無需排隊 && 讀計數<65535(16位最大值) && 狀態設置成功(讀鎖的總體計數就是在這裏改的,注意加了一個默認值的操做) if (r == 0) { //讀鎖爲0 firstReader = current; //記錄第一個獲取鎖的線程 firstReaderHoldCount = 1; } else if (firstReader == current) { //是本身重入的 firstReaderHoldCount++; } else { // HoldCounter rh = cachedHoldCounter; //用於計算讀計數的計數器 if (rh == null || rh.tid != getThreadId(current)) cachedHoldCounter = rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; //當前線程的讀計數+1 } return 1; } return fullTryAcquireShared(current); //第7行條件不知足,則for循環獲取讀鎖(實際不會死循環的) }
final int fullTryAcquireShared(Thread current) { HoldCounter rh = null; for (;;) { int c = getState(); if (exclusiveCount(c) != 0) { // 有寫鎖 if (getExclusiveOwnerThread() != current) // 寫鎖持有者不是當前線程,獲取失敗,經過aqs的doAcquireShared()進入排隊 return -1; //這裏只作了不是當前線程的判斷,若是是當前線程,這個地方不能進行排隊,由於若已有寫線程在排隊的話,就會形成死鎖,源碼中else一句的英文備註就是說這個 } else if (readerShouldBlock()) { //沒寫鎖,但可能有寫鎖在等待讀鎖釋放!!須要排隊 // 寫鎖空閒 且 公平策略決定 線程應當被阻塞 // 下面的處理是說,若是是已獲取讀鎖的線程重入讀鎖時, 即便公平策略指示應當阻塞也不會阻塞。 // 不然,這也會致使死鎖的。 if (firstReader == current) { // // assert firstReaderHoldCount > 0; } else { // threadlocal 相關處理 if (rh.count == 0) // 須要阻塞且是非重入(還未獲取讀鎖的),獲取失敗 return -1; } } if (sharedCount(c) == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { // cas 搶鎖成功 //threadlocal相關處理 return 1; } } }
protected final boolean tryReleaseShared(int unused) { Thread current = Thread.currentThread(); if (firstReader == current) {// 清理firstReader緩存 或 readHolds裏的重入計數 // assert firstReaderHoldCount > 0; if (firstReaderHoldCount == 1) firstReader = null; else firstReaderHoldCount--; } else { HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) rh = readHolds.get(); int count = rh.count; if (count <= 1) { //徹底釋放讀鎖 readHolds.remove(); if (count <= 0) throw unmatchedUnlockException(); } --rh.count; // 主要用於重入退出 } for (;;) { int c = getState(); int nextc = c - SHARED_UNIT; if (compareAndSetState(c, nextc)) // 釋放讀鎖對其餘讀線程沒有任何影響, // 但能夠容許等待的寫線程繼續,若是讀鎖、寫鎖都空閒。 return nextc == 0; } }
if (exclusiveCount(c) != 0) { if (getExclusiveOwnerThread() != current) return -1;
public void processCachedData() { readLock.lock(); if(!update){ //必須先釋放讀鎖 readLock.unlock(); //鎖降級從寫鎖獲取到開始 writeLock.lock(); try{ if(!update){ //準備數據的流程(略) update = true; } readLock.lock(); }finally { writeLock.unlock(); } //鎖降級完成,寫鎖降級爲讀鎖 } try{ //使用數據的流程 }finally { readLock.unlock(); } }