ReentrantLock是一個可重入的互斥鎖鎖, 實現Lock接口。具備與使用 synchronized 方法和語句所訪問的隱式監視器鎖相同的一些基本行爲和語義。ReentrantLock是顯示的獲取或釋放鎖,而且有鎖超時,鎖中斷等功能。java
內部維戶了一個Sync的內部類,繼承AQS隊列同步器。git
ReentrantLock 將由最近成功得到鎖,而且尚未釋放該鎖的線程所擁有。當鎖沒有被另外一個線程所擁有時,調用 lock 的線程將成功獲取該鎖並返回。若是當前線程已經擁有該鎖,此方法將當即返回。可使用 isHeldByCurrentThread() 和 getHoldCount() 方法來檢查此狀況是否發生。github
默認是非公平鎖的實現方式編程
加鎖併發
lock
方法加鎖時調用內部NonfairSync
的lock
方法,第一次會快速嘗試獲取鎖,執行AQS
類的compareAndSetState
方法(CAS)更改同步狀態成員變量state
,若是獲取成功 則設置當前線程爲鎖的持有者。失敗則執行AQS
類的acquire
方法,acquire
會調用的AQS
中的tryAcquire
方法。這個tryAcquire
方法須要自定義同步組件提供實現。tryAcquire
的具體流程是執行Sync
類的nonfairTryAcquire
方法:首先記錄當前加鎖線程,而後調用getState
獲取同步狀態,若是爲0時 說明鎖處於空閒狀態,能夠獲取,會以CAS
方式修改state
變量。成功則設置當前線程 返回true
。不然執行重入判斷,判斷當前訪問線程和已經持有鎖的線程是不是同一個。若是相同,將同步狀態值進行增長,並返回true。不然返回加鎖失敗false
解鎖函數
unlock
方法會調用內部類Sync
的tryRelease
方法。tryRelease
首先調用getState
方法獲取同步狀態,並進行了減法操做。在判斷釋放操做是否是當前線程,不是則拋出異常,而後判斷同步狀態是否等於0,若是是0,說明沒有線程持有,鎖是空閒的,則將當前鎖的持有者設置爲null
, 方便其它線程獲取,並返回true
。不然返回falsegetHoldCount()
查詢當前線程保持此鎖的次數。getOwner()
返回目前擁有此鎖的線程getQueueLength()
返回正等待獲取此鎖的線程估計數getWaitingThreads(Condition condition)
返回一個 collection,它包含可能正在等待與此鎖相關給定條件的那些線程。boolean hasQueuedThread(Thread thread)
查詢給定線程是否正在等待獲取此鎖。boolean hasQueuedThreads()
查詢是否有些線程正在等待獲取此鎖。boolean hasWaiters(Condition condition)
查詢是否有些線程正在等待與此鎖有關的給定條件boolean isHeldByCurrentThread()
查詢當前線程是否保持此鎖。void lock()
獲取鎖。void lockInterruptibly()
若是當前線程未被中斷,則獲取鎖。Condition newCondition()
返回用來與此 Lock 實例一塊兒使用的 Condition 實例。boolean tryLock()
僅在調用時鎖未被另外一個線程保持的狀況下,才獲取該鎖。void unlock()
釋放鎖程序中使用源碼分析
private ReentrantLock lock=new ReentrantLock();
private int i=0;
public void a(){
lock.lock();
i++;
lock.unlock();
}
複製代碼
package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
import java.util.Collection;
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
private final Sync sync;
/**內部維護的一個幫助類,繼承成AQS 鎖的獲取和釋放主要靠它**/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
abstract void lock();
/** * 執行非公平的t加鎖 */
final boolean nonfairTryAcquire(int acquires) {
//記錄當前加鎖線程
final Thread current = Thread.currentThread();
//獲取同步狀態 AQS中的volatile修飾的int類型成員變量 state
int c = getState();
//爲0時 說明鎖處於空閒狀態,能夠獲取
if (c == 0) {
// CAS方式修改state。成功則設置當前線程 返回true
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//線程重入判斷,判斷當前訪問線程和已經持有鎖的線程是不是同一個
else if (current == getExclusiveOwnerThread()) {
//將同步狀態值進行增長
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
//設置同步狀態,重入鎖的話就累加,並返回true
setState(nextc);
return true;
}
return false;
}
//釋放鎖,就是把AQS中的同步狀態變量就行類減直到0 就是出於空閒狀態了
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
//若是釋放操做不是當前線程 則拋出異常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//同步狀態等於0,說明沒有線程持有,鎖是空閒的
if (c == 0) {
free = true;
//當前鎖的持有者 設置爲null 方便其它線程獲取
setExclusiveOwnerThread(null);
}
//若是該鎖被獲取了n次,那麼前(n-1)次tryRelease(int releases)方法必須返回false
setState(c);
return free;
}
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
//返回目前擁有此鎖的線程,若是此鎖不被任何線程擁有,則返回 null。
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
//查詢當前線程保持此鎖的次數。
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
//查詢鎖是否被持有
final boolean isLocked() {
return getState() != 0;
}
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}
//非公平的 Sync的子類
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
//第一次快速獲取鎖,使用CAS 方式 成功設置當前線程爲鎖的持有者
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
//鎖獲取失敗時,調用AQS的acquire去獲取鎖,
//acquire會調用tryAcquire方法,tryAcquire須要自定義同步組件提供實現,
//因此這裏的調用邏輯是acquire-》tryAcquire(NonfairSync類的)-》Sync的nonfairTryAcquire方法
acquire(1);
}
//調用父類nonfairTryAcquire 實現加鎖
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
//公平的 Sync的子類
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
// 加鎖 調用AQS中的acquire方法,acquire會調用下面的tryAcquire方法
final void lock() {
acquire(1);
}
//加鎖的過程,和父類的調用父類nonfairTryAcquire方法大體同樣
//惟一不一樣的位置爲判斷條件多了hasQueuedPredecessors()方法
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//公平鎖實現的關鍵點hasQueuedPredecessors
/** 即加入了同步隊列中當前節點是否有前驅節點的判斷 若是該方法返回true,則表示有線程比當前線程更早地請求獲取鎖 所以須要等待前驅線程獲取並釋放鎖以後才能繼續獲取鎖 */
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;
}
}
//AQS中的方法 判斷當前線程是否位於CLH同步隊列中的第一個。若是是則返回true,不然返回false。
public final boolean hasQueuedPredecessors() {
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());
}
//默認的構造函數 非公平鎖
public ReentrantLock() { sync = new NonfairSync();}
//爲true 公平鎖
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
public void lock() { sync.lock();}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock() { return sync.nonfairTryAcquire(1);}
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
//釋放鎖
public void unlock() { sync.release(1);}
public Condition newCondition() {return sync.newCondition();}
public int getHoldCount() { return sync.getHoldCount(); }
public boolean isHeldByCurrentThread() { return sync.isHeldExclusively(); }
public boolean isLocked() {return sync.isLocked(); }
public final boolean isFair() { return sync instanceof FairSync; }
protected Thread getOwner() {return sync.getOwner(); }
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
public final boolean hasQueuedThread(Thread thread) { return sync.isQueued(thread);}
public final int getQueueLength() { return sync.getQueueLength(); }
protected Collection<Thread> getQueuedThreads() { return sync.getQueuedThreads(); }
public boolean hasWaiters(Condition condition) {
if (condition == null) throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
public int getWaitQueueLength(Condition condition) {
if (condition == null) throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null) throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
}
複製代碼