干货ReentrantLock非公平锁源码分析
时间:2025-11-05 11:52:55 出处:应用开发阅读(143)

本文转载自微信公众号「Java极客技术」,干货公平作者鸭血粉丝。锁源转载本文请联系Java极客技术公众号。码分
1.锁
java中,干货公平加锁的方式
synchronized,这个是锁源 java 底层实现的,也就是 C 语言实现的。 . lock,码分这个是干货公平 java.util.concurrent 包下面的,是锁源 java语言实现的。2.ReentrantLock
ReentrantLock 是码分 Lock 的一种实现,是干货公平一种可重入的公平或非公平锁。默认是锁源非公平锁。
2.1 Lock的码分创建
首先看下锁的创建和使用代码:
//创建锁 Lock lock = new ReentrantLock(); //加锁 lock.lock(); //释放锁 lock.unlock();然后看下创建的是 ReentrantLock 的构造函数:
public ReentrantLock() { sync = new NonfairSync(); }NonfairSync 就是非公平锁。所以 ReentrantLock 默认是干货公平非公平锁的云服务器提供商实现
2.2 lock()
加锁的逻辑就比较复杂了,因为存在线程竞争。锁源所以有两种情况,码分一种是竞争到锁的处理,一种是没有竞争到锁的处理。
首先我们还是来看下 lock() 方法,因为最终是非公平的实现,所以直接看 NonfairSync 里面的 lock 方法。
final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); }2.3 没有获取到锁的逻辑 acquire()
直接上代码:
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }还是3个方法,阿粉一个一个的说。
tryAcquire(arg) ,还是先看代码在分析。
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }a. 获取 state ,如果等于0,说明之前获得锁的线程已经释放了,那么这个线程就会再次去竞争锁,这就是非公平锁的体现,源码下载如果是公平锁,是没有这个判断的。
b. 如果前一个获得锁的线程没有释放锁,那么就判断是否是同一个线程,是的话就会将 state 加 1。这个就是重入锁的体现。
c. 如果都不满足,那么返回 false。
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) ,再次获取锁没有成功,并且又不是可重入锁,那么就存入一个阻塞队列里面。里面还有一点逻辑,就不展开了,有兴趣可以自己看下。
selfInterrupt(); 这个是当前线程的中断标志,作用就是在线程在阻塞的是否,客户端通过调用了中断线程的方法 interrupt(),那么该线程被唤醒的时候,WordPress模板就会有响应的处理。具体要看这个线程 run 方法里面的代码逻辑。
2.4 unlock()
protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; }state - 1,如果大于0,说明释放的是重入锁,只需要修改 state 就行了
如果等于0,说明要释放锁,释放锁首先需要把独占线程设置为null,再把state设置为0。
3 总结
Lock 锁的实现:
互斥性:需要一个状态来判断是否竞争到锁:state 并且需要用 volatile修饰,保证线程之间的可见性。
可重入性:Thread exclusiveOwnerThread 这个成员变量来记录当前获得锁的线程。
公平或非公平:默认非公平,NonfairSync。
没有竞争到锁的线程怎么办?放到队列中。
没有竞争到锁的线程怎么释放CPU?park:阻塞线程释放CPU资源,这个操作在 acquireQueued(),阿粉没没有讲这个。
最后来张流程图:

猜你喜欢
- iPhone4S5.0.1系统的优势与功能(探索iPhone4S5.0.1系统的卓越性能与创新特点)
- 浪潮云洲工业互联网平台V6.0正式发布
- Nginx 动态编译加载第三方流媒体服务模块:Nginx-RTMP-Module
- 紫光同芯高端旗舰级R52+内核车规MCU THA6412重磅发布
- ubuntu安装了wine qq怎么去卸载呢?下面我们分别来演示如何卸载它们1、安装wine按ctrl+alter+T打开终端输入以下两条命令sudo apt-get updatesodo apt-get install wine安装时间有点长,请耐心的等候2、按钮选择期间有个软件包的配置图像界面,需要用户使用tab键选定ok然后下一个条出另一个框,这里移动左右键盘,选择YES。按下enter键进行安装、、、、、3、安装wine-qq下载wine-qq的网址:http://www.longene.org/download/sudo dpkg -i WineQQ2013-xxx(你下载的QQ web包)4、卸载wine-qqsudo dpkg --purge wine-qq2012-longeneteam
- 构建弹性数据中心的能源波动性挑战和解决方案
- 我们一起聊聊Tomcat和Jetty中的对象池技术
- 英特尔谢晓清:以开源开放生态破圈x86安卓,赋能更多应用优化与开发
- 佳能242.8挂机镜头的全面评测(探索佳能242.8挂机镜头的性能和适用性能力)