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

ReentrantLock 用法与源码剖析笔记

📒 ReentrantLock 用法与源码剖析笔记


🚀 一、ReentrantLock 核心特性
  • 🔄 可重入性:同一线程可重复获取锁(最大递归次数为 Integer.MAX_VALUE
  • 🔧 公平性:支持公平锁(按等待顺序获取)和非公平锁(默认,允许插队)
  • 超时机制tryLock(long timeout, TimeUnit unit)
  • 🚫 可中断lockInterruptibly() 允许响应中断
  • 🔗 条件变量Condition 实现精准线程唤醒(对比 Object.wait/notify

🛠️ 二、基础用法模板
ReentrantLock lock = new ReentrantLock();
// 非公平锁(默认) vs 公平锁(new ReentrantLock(true))lock.lock();  // 📌 阻塞获取锁
try {// 临界区代码
} finally {lock.unlock();  // ⚠️ 必须放在 finally 块!
}// 高级用法示例
if (lock.tryLock(1, TimeUnit.SECONDS)) {  // ⏳ 带超时尝试try {// ...} finally {lock.unlock();}
}

🔍 三、源码架构分析

image-20250225234605218

  1. Sync 同步器(继承 AQS)

    • NonfairSync(非公平锁实现)
    • FairSync(公平锁实现)
  2. AQS 核心机制

    • state 字段:锁状态计数器(0=未锁定,>0=锁定次数)
    • CLH 队列:线程等待队列(双向链表实现)

⚙️ 四、关键方法源码解析
🔑 1. lock() 方法对比
// 非公平锁实现
final void lock() {if (compareAndSetState(0, 1))  // 🚀 直接尝试插队setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);
}// 公平锁实现
final void lock() {acquire(1);  // ⚖️ 必须排队
}// AQS 核心方法
public final void acquire(int arg) {if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();
}
🔄 2. tryAcquire 差异
// 非公平锁 tryAcquire
protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);  // 🎲 允许插队
}// 公平锁 tryAcquire
protected final boolean tryAcquire(int acquires) {if (getQueueLength() > 0 && getExclusiveOwnerThread() != Thread.currentThread()) {return false;  // 🚧 队列有等待线程时禁止获取}// ...后续与非公平锁相同
}

💡 五、设计亮点与注意事项
  • 性能取舍:非公平锁吞吐量更高(减少线程切换),但可能产生线程饥饿
  • 锁释放必须:unlock() 必须执行(建议用 try-finally 包裹)
  • 🧵 Condition 高级用法:实现多条件等待(典型应用:生产者-消费者模型)
  • ⚠️ 避免死锁:加锁顺序要一致,超时机制可作为兜底

📊 六、与 synchronized 对比
特性ReentrantLocksynchronized
实现机制API 层面JVM 内置
锁释放必须显式 unlock()自动释放
公平性可配置非公平
中断响应支持不支持
条件变量多 Condition单 Object monitor
性能高竞争时更优优化后差距缩小

🌟 七、最佳实践建议
  • 🆚 优先选择:需要高级功能时用 ReentrantLock,简单场景用 synchronized
  • 🧪 锁测试:用 ThreadMXBean 检测死锁
  • 📏 锁粒度:尽量缩小锁作用域
  • 🧮 性能监控:关注 getQueueLength() 等统计方法
http://www.lryc.cn/news/542854.html

相关文章:

  • 矩阵的 正定(Positive Definite)与负定(Negative Definite):从Fisher信息矩阵看“曲率”的秘密
  • 被裁20240927 --- WSL-Ubuntu20.04安装cuda、cuDNN、tensorRT
  • uniapp写的h5跳转小程序
  • [SWPUCTF 2022 新生赛]ez_rce
  • 递归、搜索与回溯算法 —— 名词解析
  • 【docker】docker swarm lock和unlock的区别,以及旧节点重启的隐患
  • Grafana使用日志5--如何重置Grafana密码
  • ELK搭建初入
  • JVM 高级面试题及答案整理,最新面试题
  • 第9章:LangChain结构化输出-示例5(基于大模型如何精确匹配POJO的字段)
  • ref和reactive的区别 Vue3
  • 基于MATLAB的OFDM通信系统仿真设计
  • 地铁站内导航系统:基于蓝牙Beacon与AR技术的动态路径规划技术深度剖析
  • JS复习练习题目、完整nodejs项目以及Commons、Es
  • Linux:理解O(1)调度算法的设计精髓
  • [C++][cmake]使用C++部署yolov12目标检测的tensorrt模型支持图片视频推理windows测试通过
  • Uppy - 免费开源、功能强大的新一代 web 文件上传组件,支持集成到 Vue 项目
  • 【游戏——BFS+分层图】
  • SSL 证书是 SSL 协议实现安全通信的必要组成部分
  • Spring 源码硬核解析系列专题(七):Spring Boot 与 Spring Cloud 的微服务源码解析
  • 嵌入式开发:傅里叶变换(5):STM32和Matlab联调验证FFT
  • C# 根据Ollama+DeepSeekR1开发本地AI辅助办公助手
  • 洛谷 P8705:[蓝桥杯 2020 省 B1] 填空题之“试题 E :矩阵” ← 卡特兰数
  • 我的AI工具箱Tauri版-FluxCharacterGeneration参考图像生成人像手办(Flux 版)
  • DeepSeek开源周Day2:DeepEP - 专为 MoE 模型设计的超高效 GPU 通信库
  • 51单片机-串口通信编程
  • python实现基于文心一言大模型的sql小工具
  • deepseek 导出导入模型(docker)
  • 前言:什么是大模型微调
  • TCPDF 任意文件读取漏洞:隐藏在 PDF 生成背后的危险