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

Java并发编程 - ReentrantLock

AQS内部属性

state(volatile修饰):为0是标记没有被占用,大于0时表示被其它线程或当前线程占用,对于ReentranLock,state可以大于1,表示多次重入,每次所释放时state减1,直至state等于0时释放锁。

head:等待队列的头节点,head后节点为null节点,链表为是双向链表,便于查找前驱和后继节点。

tail:等待队列的尾节点。

exclusiveOwnerThread:持有锁的线程。

AQS使用双向链表的原因

  1. 当某个线程出现异常不需要竞争锁,比如线程被中断了,可以快速移除链表。
  2. 通过lock()竞争锁时,需要不断的判断当前线程的前驱节点是否是head,如果是才能成功获得锁。

ReentrantLock实现原理

ReentrantLock默认使用NonfairSync实现类,NonfairSync和FairSync继承Sync,Sync是一个抽象类。

加锁流程(lock)

加锁成功(tryAcquire)

  1. 如果state=0,通过CAS尝试将state赋值为1,同时设置exclusiveOwnerThread为当前线程。
  2. 如果state!=0,判断exclusiveOwnerThread是否为当前线程,如果是当前线程state+1。

加锁失败(acquireQueued)

  1. (addWaiter)先创建Node节点,放到等待队列尾部。如果是tail节点为null,会先创建一个Dummy节点(空节点),head和tail的引用指向Dummy节点,在创建Node节点,放到等待队列尾部。

node节点如何插入到队列尾部过程

    • 把当前线程的node的prev指向tail
    • 通过cas把node节点设置为新tail
    • 把原tail节点的next指向当前node

  1. (acquireQueued)如果创建的Node节点的前驱节点是head节点,会在尝试一次锁竞争(tryAcquire),竞争失败走3。
  2. (shouldParkAfterFailedAcquire)将前驱节点的waitStatus改为-1,并返回false,再次执行acquireQueued(改成-1的作用是:告知前驱节点有责任去唤醒下一个节点)。
  3. (parkAndCheckInterrupt)阻塞当前线程。

释放锁流程(unlock)

  1. (tryRelease)state-1,当state=0时,设置exclusiveOwnerThread为null,并返回true表示锁释放成功,否则返回false。

  1. (release)判断head!=null&&head.waitStatus!=0,则表明需要唤醒head的后继节点(unparkSuccessor)。
  2. (acquireQueued),被parkAndCheckInterrupt阻塞的线程会继续执行for循环,(tryAcquire)如果竞争成功会设置当前节点为头节点,头节点的下一个节点为null(方便GC)。
  3. (acquireQueued)如果后继节点竞争失败,继续阻塞。

ReentryLock 特性

  1. 支持可重入
  2. 支持阻塞竞争锁和非阻塞竞争锁,lock()和tryLock()
  3. 支持公平和非公平锁
http://www.xdnf.cn/news/117721.html

相关文章:

  • HTML应用指南:利用GET请求获取微博签到位置信息
  • java—11 Redis
  • 基于大模型的结肠癌全病程预测与诊疗方案研究
  • 第五章:Framework/Tooling Abstraction
  • 凝聚湾区网信力量!向成电子受邀参加2025麒麟软件华南生态渠道大会
  • Go语言中包导入下划线的作用解析
  • Python学习笔记(三)(程序流程控制)
  • SEO的关键词研究与优化 第二章
  • 前端基础之《Vue(9)—混入》
  • Linux操作系统--基础I/O(上)
  • Freertos----软件定时器
  • WPS右键菜单中“上传到云文档”消失,使用命令行注册解决
  • LeetCode-Hot100
  • 数据集-目标检测系列- F35 战斗机 检测数据集 F35 plane >> DataBall
  • 【安全扫描器原理】网络扫描算法
  • 【c++】【STL库】vector类详解
  • C语言基础(day0424)
  • Java基础系列-HashMap源码解析4-基本概念
  • 各种插值方法的Python实现
  • BERT BERT
  • 精益数据分析(21/126):剖析创业增长引擎与精益画布指标
  • 4.3 工具调用与外部系统集成:API调用、MCP(模型上下文协议)、A2A、数据库查询与信息检索的实现
  • 实战交易策略 篇十九:君山居士熊市交易策略
  • 如何自己电脑上部署DeepSeek,并且接口访问?
  • 摘要 | 李录在北大光华管理学院的演讲《价值投资》
  • express的介绍,简单使用
  • ES6 模块化 与 CommonJS 的核心概念解析
  • java 富文本转pdf
  • 《100天精通Python——基础篇 2025 第1天:从编程语言到计算机基础,开启你的学习之旅》
  • 数据仓库建设全解析!