ReentrantLock
類是屬於java.util.concurrent
的。實現了Lock, java.io.Serializable
兩個接口,是一個可重入的互斥鎖,所謂可重入是線程能夠重複獲取已經持有的鎖。java
/** * Creates an instance of {@code ReentrantLock}. * This is equivalent to using {@code ReentrantLock(false)}. */ public ReentrantLock() { sync = new NonfairSync(); } /** * Creates an instance of {@code ReentrantLock} with the * given fairness policy. * * @param fair {@code true} if this lock should use a fair ordering policy */ public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
abstract static class Sync extends AbstractQueuedSynchronizer
ReentrantLock
實現鎖的機制是經過Sync
進行操做的。Sync
類是繼承AbstractQueuedSynchronizer
類的。這也就代表ReentrantLock
是基於AQS
的實現的。‘node
Sync
,FairSync
和NonFairSync
都是ReentrantLock
的靜態內部類。FairSync
和NonFairSync
又是Sync
具體實現類,分別對應的是公平鎖和非公平鎖,公平主要是指按照FIFO
原則順序獲取鎖,非公平能夠根據定義的規則來選擇得到鎖。less
非公平鎖NonFairSync
是ReentrantLock
默認的實現方式。這裏能夠看一下它的lock
實現過程:源碼分析
/** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); }
CAS
更新state
狀態,若是更新成功,則獲取鎖,設定當前線程爲鎖的擁有者。protected final boolean compareAndSetState(int expect, int update) { // See below for intrinsics setup to support this return unsafe.compareAndSwapInt(this, stateOffset, expect, update); }
acquire(1)
方法。acquire
具體實現以下:public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); }
tryAcquire
過程,將再次嘗試獲取鎖,其中tryAcquire
在靜態內部類NonfairSync
類中被重寫,具體的實現是Sync
的nonfairTryAcquire
方法:ui
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
其主要過程是先獲取state
的值,若是等於0,則經過CAS
更新state
的值。若是state
不爲0,則判斷當前線程是不是鎖的持有者,若是是,則將state
加1,返回true
。this
若是tryAcquire
仍然失敗的話,首先會調用addWaiter(Node.EXCLUSIVE)
,將當前線程加入到等待隊列的尾部。而後會調用acquireQueued
方法,acquireQueued
的做用主要是用來阻塞線程的:spa
/** * Acquires in exclusive uninterruptible mode for thread already in * queue. Used by condition wait methods as well as acquire. * * @param node the node * @param arg the acquire argument * @return {@code true} if interrupted while waiting */ final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return interrupted; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } }
這裏是一個循環自旋操做,在阻塞線程以前,首先判斷線程自身前面的節點是不是head
節點,若是是,則從新去獲取鎖,獲取成功後,返回,並取消不斷獲取的過程。若是不是,調用shouldParkAfterFailedAcquire
方法去判斷是否應該阻塞當前線程,主要是經過節點的waitStatus
來進行判斷。線程
公平鎖FairSync
和非公平鎖NonFairSync
的實現很類似,這裏比較一下二者的差異。code
FairSync
的lock
方法中沒有像NonFairSync
中先去經過CAS
操做state
去獲取鎖,而是直接經過tryAcquire
去獲取鎖。final void lock() { acquire(1); }
FairSync
版本tryAcquire
在獲取鎖的過程當中,須要先判斷隊列中是否有其餘等待的線程,若是沒有,纔回去嘗試獲取鎖。/** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
釋放鎖沒有區分公平和非公平的。主要的工做就是減少state
的值。當state
等0的時候,釋放鎖並喚醒隊裏中其餘線程來獲取鎖。orm
public void unlock() { sync.release(1); }
public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; }
protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; }
ReentrantLock
是經過AQS
的state
字段來判斷所是否被佔用。公平
與非公平
的差異是在於獲取鎖的方式是不是按照順序的。state
操做是經過CAS
實現的。經過隊列來實現因搶佔鎖被阻塞的隊列。AQS
有自旋的過程,並不是是獲取不到鎖就直接阻塞。