可重入锁ReentrantLock的公平锁和非公平锁
参考:https://z.itpub.net/article/detail/C7F9AA816D86898AB8CA9C8E4ACCBD4D
什么是AQS?
AQS即抽象同步队列AbstractQueueSynchronizer, 用于存放所有等着获取锁的排队线程,一个线程对象一个节点。
ReentrantLock 的Sync 内部类有什么作用?
Sync是一个内部抽象类, 有两个继承的子类FairSync 和 NonFairSync,表示公平锁和非公平锁。

new ReentrantLock(Boolean b) 创建的锁是否是公平的, 取决于传入的参数。
继承关系:
FairSync、 NonFairSync -> Sync -> AbstractQueuedSynchronizer (AQS ) -> AbstractOwnableSynchronizer (AOS)
公平锁实现原理:
1、 new ReentrantLock(true)
2、 调用lock 方法时,判断state = 0, 等于0表示第一次加锁, =1 表示锁重入了一次。
3、 state = 0 时:
hasQueuedPredecessors 方法判断是否有比当前线程更早的节点, 有的话直接return false获取锁失败。
如果是排队最早的节点, compareAndSetState 设置state=1 , setExclusiveOwnerThread 设置占用锁的线程为当前线程。
4、state !=0, 表示当前锁已经被人持有。 如果是正好是当前线程持有,重入一次; 如果不是返回false获取锁失败。
以下是实现源码:
1 /** 2 * Sync object for fair locks 3 */ 4 static final class FairSync extends Sync { 5 private static final long serialVersionUID = -3000897897090466540L; 6 /** 7 * Fair version of tryAcquire. Don't grant access unless 8 * recursive call or no waiters or is first. 9 */ 10 @ReservedStackAccess 11 protected final boolean tryAcquire(int acquires) { 12 final Thread current = Thread.currentThread(); 13 int c = getState(); 14 if (c == 0) { 15 if (!hasQueuedPredecessors() && 16 compareAndSetState(0, acquires)) { 17 setExclusiveOwnerThread(current); 18 return true; 19 } 20 } 21 else if (current == getExclusiveOwnerThread()) { 22 int nextc = c + acquires; 23 if (nextc < 0) 24 throw new Error("Maximum lock count exceeded"); 25 setState(nextc); 26 return true; 27 } 28 return false; 29 } 30 }
非公平锁的实现原理:
lock 方法获取锁时, 与公平锁的逻辑一样, 只是少了 hasQueuedPredecessors()方法的判断, 也就是不判断当前节点是否是头结点(排队最久的节点)

浙公网安备 33010602011771号