Java基础知识总结(80)

CLH释放锁的过程

线程A执行完临界区代码后开始unlock(释放)操作,设置nodeA的前驱引用为null(方便垃圾回收器回收),锁状态locked为false。

线程B执行抢到锁并且完成临界区代码的执行后,开始unlock(释放)操作,设置nodeB的前驱引用为null,锁状态locked为false。

线程C执行抢到锁并且完成临界区代码的执行后,开始unlock(释放)操作,设置nodeC的前驱引用为null,锁状态locked为false。

AQS解读

AQS是CLH队列的一个变种,主要原理和CLH队列差不多,AQS队列内部维护的是一个FIFO的双向链表,这种结构的特点是每个数据结构都有两个指针,分别指向直接的前驱节点和直接的后继节点。所以双向链表可以从任意一个节点开始很方便地访问前驱节点和后继节点。每个节点其实是由线程封装的,当线程争抢锁失败后会封装成节点加入AQS队列中;当获取锁的线程释放锁以后,会从队列中唤醒一个阻塞的节点。

cs自旋时,往队列末尾添加。添加完成后,自旋获取前一个节点的状态,判断前一个节点有没有释放锁,没有释放继续获取,获取到则执行同步代码块,获取不到该线程则处于死锁状态。

AQS执行流程

1、线程在获取锁失败后会被封装成节点放入同步队列的队尾,需要CAS设置

2、自旋判断前驱节点是不是头结点,如果是就获取同步状态,获取失败进入阻塞状态直到被头结点唤醒

3、获取成功,将持有同步状态的线程所在的节点设置为头节点

4、头节点线程完成任务后,释放了同步状态,然后会唤醒它的后继节点,同时后继节点的线程被唤醒后还需要检查自己的前驱节点是不是头节点

相关推荐
AI 编程助手GPT1 小时前
用 Python 做一个世界杯赛前分析脚本:以巴西 vs 摩洛哥为例
开发语言·网络·人工智能·python·chatgpt
键盘歌唱家1 小时前
Spring AI 入门分享:它和“直接调 API“到底差在哪
java·人工智能·spring
lihao lihao1 小时前
Linux信号
开发语言·c++·算法
Java患者·1 小时前
《Python 人脸识别入门实践:从人脸检测到人脸比对完整实现》
开发语言·python·opencv·目标检测·计算机视觉·目标跟踪·视觉检测
ceclar1232 小时前
C# 的任务并行库(TPL)
开发语言·c#·.net
宸丶一2 小时前
Day 10:LangGraph - Agent 的图执行引擎
java·windows·python
hikktn2 小时前
Excel 导出 OOM 预防实战:30 万行从堆溢出到 50MB 的演进
java·excel·easyexcel
快乐的哈士奇2 小时前
【Next.js实战①】Gmail API 按柜号检索邮件:OAuth 双 Cookie 与搜索 Fallback
开发语言·javascript·ecmascript
风味蘑菇干2 小时前
WTomcat服务器
java·服务器
weixin_307779132 小时前
Python写入Shell文件使用Linux系统的换行符
linux·开发语言·python·自动化