對於Reentranlock的用法,對比Synchronized多了 定時守候、可中斷守候、公平和非公平。本文重點就Reentranlock 中的代碼實現作一個分析。而對於其與Synchronize 區別可參考下文。java
能夠參考深刻研究 Java Synchronize 和 Lock 的區別與用法http://my.oschina.net/softwarechina/blog/170859node
FairSync NonFairSync 二者都是java.util.concurrent包中同步類中如Semaphere,Reentranlock 等類中的內部類,二者繼承自 AQS,而Reentranlock中的 二者代碼以下所示,爲獨佔模式。二者都實現了tryAcquire,與lock方法。less
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)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }
Reentranlock 根據參數,肯定使用哪一種同步器,默認是NonFairSync。從代碼分析出,NonFairSync最大的特色是,調用lock時,會先嚐試去獲取資源,而獲取不一樣,則經過父類的acquire(1)方法,調用各自子類的tryAcquire方法,以下。而對於NonFairSync,在一次執行父類Sync中的方法,在一次嘗試獲取資源。ui
然而對於FairSync的lock,直接調用acquire,少了一次直接獲取的過程,接着調用子類的tryAcquire方法,當有資源空閒時,並不像NonFair 直接嘗試get,而是先判斷當前線程是否隊列頭部的線程,或者是空的queue,則嘗試獲取。不然判斷當前線程是不是佔用資源的線程。若是是,則將state+1,表示該線程調了屢次lock,釋放時要調同等次數的unlock,才能釋放資源。.net
static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; final void lock() { acquire(1); } /** * 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() && //當前Thread是不是head節點的next節點線程,由於公平的鎖,按順序獲取資源 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; } }
接着上一步,二者都沒有獲取到資源時,將執行同樣的流程,可是執行到tryAcqure方法時,會根據不一樣子類實現的來執行。線程
以下代碼,首先code
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
而對於 Reentranlock 的其它功能如 中斷守候,超時等,都是針對這些條件作了額外的操做。orm