当前位置: 首页 > ops >正文

并发编程艺术--AQS底层源码解析(三)

本章我们继续AQS的源码解析,ReentrantLock本身是重入锁,之前解析了很多关于ReentrantLock的源码但是可重入锁这部分却没有谈及接下来讲一下重入锁是如何实现的。

可重入锁:

对于ReentrantLock的可重入锁的具体实现逻辑是在tryAcquire这个方法中实现的,本身AQS是没有这个方法的具体业务逻辑的交给子类去实现的而ReentrantLock中的Sync继承了AQS并且去实现了tryAcquire,在tryAcquire方法中定义了如何处理重入锁的逻辑。

 protected final boolean tryAcquire(int var1) {Thread var2 = Thread.currentThread();int var3 = this.getState();if (var3 == 0) {if (!this.hasQueuedPredecessors() && this.compareAndSetState(0, var1)) {this.setExclusiveOwnerThread(var2);return true;}} else if (var2 == this.getExclusiveOwnerThread()) {int var4 = var3 + var1;if (var4 < 0) {throw new Error("Maximum lock count exceeded");}this.setState(var4);return true;}return false;}

两个if条件判断分别是判断锁是否被占用,然后判断当前线程持有锁线程是否为本线程。

第一个判断的内部逻辑主要是公平锁校验的(这个后续会说),第二个则是可重入锁判定的

getExclusiveOwnerThread方法返回值是当前持有锁的线程对象,与本线程对象进行比对如果是同一个对象则证明当前是重入锁逻辑操作将state状态变量进行加一。

可以看出每次重入锁的时候都会将state同步量加一,这样就能对其锁的重入次数进行技术,那么每次释放锁的时候都会进行减一直到最后为0的时候才会真正的释放锁。顺带我们看一下释放锁的过程。释放锁则是tryRelease方法来实现的。

  protected final boolean tryRelease(int var1) {int var2 = this.getState() - var1;if (Thread.currentThread() != this.getExclusiveOwnerThread()) {throw new IllegalMonitorStateException();} else {boolean var3 = false;if (var2 == 0) {var3 = true;this.setExclusiveOwnerThread((Thread)null);}this.setState(var2);return var3;}}

首先将状态值扣减,并且进行判断如果状态值为0则释放锁,将当前持有锁的线程置为null,然后设置状态值,最后返回boolean类型值表示是否完成了锁释放。

公平锁和非公平锁:

如果一个锁是公平的那么获取资源的顺序就应该满足FIFO队列中的顺序,否则则不为公平锁。公平锁能尽可能的减少线程饥饿,但是相比于非公平锁的性能则会差不少。

前面代码中hasQueuedPredecessors则是公平锁的校验代码

    public final boolean hasQueuedPredecessors() {Node var1 = this.tail;Node var2 = this.head;Node var3;return var2 != var1 && ((var3 = var2.next) == null || var3.thread != Thread.currentThread());}

主要业务逻辑是查看是否队列前面是否有其他线程在等待,如果有则返回false,借此来进行公平锁校验

对于非公平锁则是通过nonfairTryAcquire来进行

final boolean nonfairTryAcquire(int var1) {Thread var2 = Thread.currentThread();int var3 = this.getState();if (var3 == 0) {if (this.compareAndSetState(0, var1)) {this.setExclusiveOwnerThread(var2);return true;}} else if (var2 == this.getExclusiveOwnerThread()) {int var4 = var3 + var1;if (var4 < 0) {throw new Error("Maximum lock count exceeded");}this.setState(var4);return true;}return false;}

可以看出非公平锁与公平锁的区别就在于当判断到资源没有被占用的时候,公平锁则是再判断一下是否该到自己了,而非公平锁则是直接进行CAS占有锁操作。

对于ReentrantLock来说默认是非公平锁。

下一章节我们将来介绍LockSupport阻塞线程工具类,以及Condition基于等待队列的线程唤醒与等待工具类

http://www.xdnf.cn/news/9083.html

相关文章:

  • 华为OD机试真题——构成正方形的数量(2025B卷:100分)Java/python/JavaScript/C++/C/GO六种最佳实现
  • P2340 [USACO03FALL] Cow Exhibition G
  • 时序模型上——ARIMA/
  • 云蝠 Voice Agent:开启大模型时代语音交互新纪元
  • AAOS系列之(四) ---APP端如何获取CarService中的各个服务代理
  • day8补充(中断驱动和队列缓冲实现高效数据处理)
  • day020-sed和find
  • 【C++高阶一】二叉搜索树
  • Speech Synthesis/Text to Speech(TTS)
  • 写给这个阶段自我的一封信
  • Solr搜索:比传统数据库强在哪?
  • 【Ai】使用Ultralytics yolo做图片检测+使用roboflow做数据标注
  • 机器学习与深度学习5:pytorch前馈神经网络FNN实现手写数字识别
  • Halcon仿射变换---个人笔记
  • PySide6 GUI 学习笔记——常用类及控件使用方法(光标类图标QCursor)
  • 918. 环形子数组的最大和
  • 消费电子卷入“技术军备竞赛”
  • shell脚本基础
  • 记忆上传与自我同一性的哲学-技术综合分析
  • AI日报 - 2025年05月26日
  • 快速了解GO之Channel 通道
  • uv ——新的python包管理工具
  • 如何在 ONLYOFFICE 演示文稿中调整段落首行缩进
  • 第10章 网络与信息安全基础知识
  • 【分治】数组中的逆序对
  • 格恩朗管段超声波流量计:流量测量先锋
  • SD-WAN与传统网络结合:轨道交通网络优化的高效实践与深度解析
  • Day37打卡 @浙大疏锦行
  • 数据库入门:以商品订单系统为例
  • Nuxt.js vs Next.js:Vue 与 React 阵营的 SSR 双雄对比