对于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