可重入锁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()方法的判断, 也就是不判断当前节点是否是头结点(排队最久的节点)

 

posted @   huhu_li  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示