圖1-1java
根據上圖能夠知道,ReenTrantLock繼承了Lock接口,Lock接口聲明方法以下:ui
方法名 | 說明 | 拋出異常 |
---|---|---|
lock() | 一直阻塞獲取鎖,直到獲取成功 | 無 |
lockInterruptibly() | 嘗試獲取鎖,直到獲取鎖或者線程被中斷 | InterruptedException |
tryLock() | 嘗試獲取空閒的鎖,獲取成功返回true,獲取失敗返回false,不會阻塞,當即返回 | 無 |
tryLock(long time, TimeUnit unit) | 嘗試在time時間內獲取空閒的鎖,在等待時間內能夠被中斷 | InterruptedException |
unlock() | 釋放鎖 | 無 |
newCondition() | 返回當前鎖的一個condition實例,用於條件性等待 | 無 |
1.ReentrantLock的部分方法spa
圖2-1線程
Sync是NonfairSync 和FairSync 的父類,聲明方法以下:code
/** * 抽象方法,獲取鎖 */ abstract void lock(); /** * 實現非公平鎖獲取邏輯 */ final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); //父類同步器方法,獲取當前同步狀態,後續文章會分析 if (c == 0) {//狀態等於0表示沒有獲取到鎖 if (compareAndSetState(0, acquires)) { //CAS方式修改狀態 setExclusiveOwnerThread(current); //修改爲功後設置當前線程爲鎖的全部者 return true; } } else if (current == getExclusiveOwnerThread()) {//當前鎖已被佔用,判斷是否是本身獲取到了鎖,鎖重入 int nextc = c + acquires; //獲取鎖的計數器 if (nextc < 0) // overflow //由於是int類型,若是超過int最大值會溢出爲負 throw new Error("Maximum lock count exceeded"); setState(nextc);//設置計數器爲狀態值 return true; } return false; } protected final boolean tryRelease(int releases) { int c = getState() - releases;//釋放鎖,同步狀態減int值 if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); //若是當前相差不是鎖的擁有者,拋出異常 boolean free = false; if (c == 0) { //若是同步狀態值爲0,表示鎖已經釋放成功 free = true; setExclusiveOwnerThread(null); // 設置鎖的擁有線程爲null } setState(c);//從新賦值同步狀態 return free; } //判斷當前線程是否是鎖獨佔 protected final boolean isHeldExclusively() { return getExclusiveOwnerThread() == Thread.currentThread(); } //返回鎖的ConditionObject實例 final ConditionObject newCondition() { return new ConditionObject(); } // Methods relayed from outer class //獲取當前佔有鎖的線程 final Thread getOwner() { return getState() == 0 ? null : getExclusiveOwnerThread(); } //獲取當前鎖計數 final int getHoldCount() { return isHeldExclusively() ? getState() : 0; } //判斷是否獲取到鎖 final boolean isLocked() { return getState() != 0; //能夠知道判斷獲取鎖的關鍵就是是否不等於0 } 複製代碼
static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; /** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void lock() { if (compareAndSetState(0, 1))//CAS獲取鎖 setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } } 複製代碼
lock()
和tryAcquire(int acquires)
方法,其中和tryAcquire(int acquires)
方法直接調用了父類的nonfairTryAcquire(acquires)
,介紹父類的時候已經解析過,不清楚能夠看上文Sync解析部分。根據lock源碼發現,開始判斷是不是第一次獲取鎖,若是獲取鎖成功,就把當前線程設置爲鎖的佔有者,不然調用父類的acquire(1)
方法(下一篇介紹同步器會介紹)。static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; /**調用父類的acquire()方法*/ final void lock() { acquire(1); } /** * 嘗試獲取鎖 */ 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; } } 複製代碼
!hasQueuedPredecessors()
判斷,其實該方法就是判斷是否有比當前線程等待最長時間的線程,若是沒有,那麼就嘗試獲取鎖,獲取成功後設置當前線程爲鎖的佔有者,因此,公平與不公平就是是否按照時間等待來獲取鎖的,好比食堂吃飯,排隊一個個來,這就是公平,若是有人插隊,這就是不公平。public ReentrantLock() { sync = new NonfairSync(); } 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); } //指定超時時間內獲取鎖,阻塞時間爲timeout public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } public Condition newCondition() { return sync.newCondition(); } public int getHoldCount() { return sync.getHoldCount(); } public boolean isHeldByCurrentThread() { return sync.isHeldExclusively(); } 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); } 複製代碼
sync
,在介紹sync
時候已經說過,它就是繼承了AbstractQueuedSynchronizer
同步器,不少方法都是直接調用父類同步器的方法,下一篇《java鎖之ReentrantLock(二)》會重點解析AbstractQueuedSynchronizer
同步器源碼,分析同步器是如何依託於FIFO隊列完成鎖的機制。