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

并发编程艺术--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基于等待队列的线程唤醒与等待工具类

相关文章:

  • 使用NSIS 和 VNISEdit 打包 electron 程序为 exe 向导式安装包
  • m1 运行renrenfastvue出现的问题和解决方案
  • C 语言学习笔记二
  • 知道Metasploit 吗?
  • 3561.移除相邻字符
  • 【LangChain表达式语言(LCEL)应用实践】
  • 军事大模型及其应用分析
  • TPAMI 2025 | CEM:使用因果效应图解释底层视觉模型
  • 链表面试题10之随机链表的复制
  • MySQL数据库零基础入门教程:从安装配置到数据查询全掌握
  • MySQL增删改查基础教程:熟练掌握DML语句操作【MySQL系列】
  • 58、【OS】【Nuttx】编码规范解读(六)
  • java每日精进 5.26【本地缓存】
  • Java----自动装箱和自动拆包 与 泛型
  • 基数排序---Java版本
  • springboot上传文件
  • 浏览器指纹科普 | 语言 vs 界面语言,区别是什么?
  • 解锁集成电路制造新建项目的防震黑科技-江苏泊苏系统集成有限公司
  • 纯彩天气隐私政策
  • java高级 -动态代理
  • 建设部网站工程设计收费标准/百度云在线登录
  • 做网站绿标/今日新闻快讯
  • c2c电子商务/天津seo公司
  • 搜网站网/站长素材网站官网
  • 产品网站建设/天津建站网
  • 大连辰熙大厦做网站/江苏搜索引擎优化公司