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

基于AQS实现Reentrantlcok

好久没有更新了
这次来补充上一次AQS还没有实现的可重入锁部分!
我们知道ReentrantLock是可重入的锁,主要的核心是state,他是一个原子性的整数,我们只需要将获取锁的代码boolean由false到true变成0->1即可完成。在完成删除逻辑时如果锁的state>1我们就将state–,而不用释放锁,否则,我们释放这个锁即可
下面是详细的代码,修改自我之前的文章:70行代码手写AQS,感兴趣的可以去看看;
以后面对面试官问起这个问题时,可以大大方方的说,我会!

package com.max;import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;public class MyLock {// 锁状态:0 表示未加锁,1 表示已加锁;支持可重入AtomicInteger state = new AtomicInteger(0);// 当前持有锁的线程Thread own = null;// 虚拟头节点(不代表真实线程),用于构建等待队列的链表结构AtomicReference<Node> head = new AtomicReference<>(new Node());// 队列的尾节点,初始指向头节点AtomicReference<Node> tail = new AtomicReference<>(head.get());/*** 获取锁的主方法:* - 无竞争时直接加锁成功;* - 否则将当前线程加入等待队列并自旋等待;* - 成为头节点时尝试抢锁。*/public void lock() {// 快速路径:尝试获取锁if (state.get() == 0) {if (state.compareAndSet(0, 1)) {System.out.println(Thread.currentThread().getName() + " 直接拿到了锁");own = Thread.currentThread();return;}} else {// 支持可重入锁if (own == Thread.currentThread()) {state.incrementAndGet();return;}}// 构造当前线程对应的节点Node curr = new Node();curr.thread = Thread.currentThread();// 将节点加入等待队列(尾插法,保证顺序)while (true) {Node currTail = tail.get();if (tail.compareAndSet(currTail, curr)) {System.out.println(Thread.currentThread().getName() + " 加入到了链表尾部");curr.prev = currTail;     // 设置前驱节点currTail.next = curr;     // 设置前一个尾节点的后继break; // 加入成功,退出循环}// CAS失败则重试}// 自旋等待获取锁while (true) {// 当前线程是队头的下一个,尝试抢锁if (curr.prev == head.get() && state.compareAndSet(0, 1)) {own = Thread.currentThread();  // 设置锁持有者head.set(curr);                // 将当前节点设为头节点curr.prev.next = null;         // 清理旧头节点的引用,帮助GCcurr.prev = null;              // 断链System.out.println(Thread.currentThread().getName() + " 被唤醒后拿到了锁");return;}// 不是轮到当前线程,挂起自己LockSupport.park();}}/*** 解锁方法:* - 检查是否为持锁线程;* - 可重入情况则递减计数;* - 非重入最后一次解锁后,唤醒下一个等待线程。*/public void unlock() {// 非锁持有线程调用会抛异常if (Thread.currentThread() != this.own) {throw new IllegalStateException("当前线程没有锁,不能解锁");}int i = state.get();// 可重入支持:只减计数,不释放锁if (i > 1) {state.set(i - 1);return;}// 获取当前队列头节点和下一个节点Node headNode = head.get();Node next = headNode.next;// 释放锁状态state.set(0);// 如果存在后继线程,唤醒它if (next != null) {System.out.println(Thread.currentThread().getName() + " 唤醒了 " + next.thread.getName());LockSupport.unpark(next.thread);}}/*** 队列节点类:* - 用于构建等待线程的链表;* - 每个节点包含线程引用及双向链表指针。*/class Node {Node prev;       // 前驱节点Node next;       // 后继节点Thread thread;   // 当前节点绑定的线程}
}
http://www.xdnf.cn/news/4943.html

相关文章:

  • 【递归、搜索和回溯】递归、搜索和回溯介绍及递归类算法例题
  • LeetCode百题刷002摩尔投票法
  • 镜头内常见的马达类型(私人笔记)
  • Nginx静态资源增加权限验证
  • CurrentHashMap的整体系统介绍及Java内存模型(JVM)介绍
  • 单位代码签名证书是什么?如何申请?
  • 开平机:从原理到实践的全面技术剖析
  • 【C/C++】范围for循环
  • ⭐️⭐️⭐️【课时1:大模型是什么?】学习总结 ⭐️⭐️⭐️ for《大模型Clouder认证:基于百炼平台构建智能体应用》认证
  • 【el-admin】el-admin关联数据字典
  • 访问网站提示“不安全”“有风险”怎么办?
  • HarmonyOS NEXT 免费无广告看电影app:从想法到实现的经验总结
  • AI与自然语言处理(NLP):从BERT到GPT的演进
  • Python字典:数据操作的核心容器
  • 单调栈所有模版(2)
  • 19、HashTable(哈希)、位图的实现和布隆过滤器的介绍
  • 报考消防设施操作员需要满足什么条件?
  • 【Python 字典(Dictionary)】
  • 【Pandas】pandas DataFrame all
  • levelDB的数据查看(非常详细)
  • 摩斯密码详解
  • 基于论文《大规模电动汽车充换电设施可调能力聚合评估与预测》开发者说明文档
  • EXCEL中嵌入其他表格等文件
  • 电子电路:白炽灯发光能说明电子正在消散消失吗?
  • 小刚说C语言刷题—1004阶乘问题
  • 深入了解阻塞队列的实现
  • MySQL性能分析工具:SHOW PROCESSLIST
  • Mac电脑远程连接window系统服务器
  • 自定义分区器
  • 车载以太网转USB接口工具选型指南(2025版)