Java多线程知识梳理(3) 作者没有四次元口袋的蓝胖日期2026-07-06标签Java, 多线程, ReentrantLock, AQSJava多线程知识梳理(3)一、ReentrantLock 原理ReentrantLock可重入锁是 Java 并发包JUC中的核心类基于AQSAbstractQueuedSynchronizer实现功能比 synchronized 丰富得多。1.1 什么是可重入重入同一线程在外层获取锁后在内层再次获取同一把锁时不会死锁而是直接成功。ReentrantLocklocknewReentrantLock();publicvoidmethodA(){lock.lock();// 外层获取锁try{methodB();// 调用 B}finally{lock.unlock();// 外层释放锁}}publicvoidmethodB(){lock.lock();// 内层再次获取同一把锁 —— 如果不可重入就会死锁try{System.out.println(B);}finally{lock.unlock();// 必须成对释放}}ReentrantLock 通过维护一个state变量AQS 中的实现可重入第一次获取锁state 0 → 1同一线程重入state 1 → 2 → 3…每次释放锁state 递减到 0 时真正释放注意synchronized 也是可重入的通过对象头的 Mark Word 记录持有线程ID和重入次数。1.2 AQS 核心原理简述AQS 是 ReentrantLock 的底层骨架核心结构AQS ├── state同步状态int类型 ├── CLH 队列双向链表存储等待的线程 │ └── Node { thread, waitStatus, prev, next } └── 核心方法acquire()、release()、tryAcquire()、tryRelease()工作流程线程尝试获取锁失败则包装成 Node 加入 CLH 队列每个 Node 通过自旋或 park阻塞等待前驱节点的释放锁释放时唤醒队列中的下一个节点1.3 公平锁 vs 非公平锁ReentrantLockfairLocknewReentrantLock(true);// 公平锁ReentrantLockunfairLocknewReentrantLock(false);// 非公平锁默认对比公平锁非公平锁获取顺序严格按 FIFO 顺序允许插队CAS 尝试获取性能较低要维护队列顺序较高减少线程切换饥饿不会新线程可能抢到锁导致等待久的线程延迟实现区别获取锁时必须检查队列中是否有等待线程直接 CAS 抢锁抢不到才进队列非公平锁获取流程线程来了直接 CAS 尝试抢锁不排队抢到 → 返回成功抢不到 → 检查 state如果是可重入则直接获取否则加入 CLH 队列尾部等待公平锁获取流程线程来了先检查队列是否为空队列不为空 → 老老实实排到队尾队列为空 → 才尝试 CAS 抢锁 绝大多数场景用非公平锁性能更好。公平锁只有在对响应时间公平性有严格要求时才使用。1.4 ReentrantLock 的常用方法方法说明lock()阻塞式获取锁不可中断lockInterruptibly()可中断获取锁等待时响应中断tryLock()非阻塞尝试获取锁立即返回 true/falsetryLock(long time, TimeUnit unit)指定时间内尝试获取超时返回 falseunlock()释放锁必须在 finally 中调用isLocked()查询当前是否有线程持有锁getHoldCount()查询当前线程重入次数1.5 正确用法模板ReentrantLocklocknewReentrantLock();publicvoiddoSomething(){lock.lock();// 必须在 try 之外try{// 临界区代码}finally{lock.unlock();// 必须 finally 释放否则异常时永远锁死}}// 可中断版本publicvoiddoSomethingInterruptible(){try{lock.lockInterruptibly();try{// 临界区代码}finally{lock.unlock();}}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}⚠️常见坑lock() 放在 try 里如果 lock() 本身抛异常finally 中的 unlock() 会释放一个没被持有的锁导致 IllegalMonitorStateException。二、ReentrantLock vs synchronized 深度对比对比维度synchronizedReentrantLock实现层面JVM 关键字monitorenter/monitorexitJDK API基于 AQS锁释放JVM 自动释放必须手动 unlock()放在 finally可中断不可中断阻塞等可中断lockInterruptibly超时获取不支持tryLock(time)尝试获取不支持tryLock() 非阻塞公平性非公平可选公平/非公平条件变量只有一个Object 的 wait/notify可绑定多个 Condition锁升级有无锁→偏向→轻量级→重量级无直接重量级性能JDK6 后优化锁升级略低于优化后的 synchronized代码简洁性简洁关键字即可繁琐必须 try-finally2.1 什么时候选谁选 synchronized简单的同步代码块/方法对性能要求不高、代码简洁优先不需要特殊锁功能选 ReentrantLock需要公平锁需要响应中断 / 超时获取需要 tryLock 非阻塞尝试需要多个 Condition如生产者-消费者模式需要细粒度的锁控制 阿里 Java 开发手册强制要求在使用锁时优先选择 Lock 接口ReentrantLock因为其功能更丰富。2.2 Condition更细粒度的条件控制ReentrantLocklocknewReentrantLock();ConditionnotFulllock.newCondition();// 生产者等待ConditionnotEmptylock.newCondition();// 消费者等待// 生产者lock.lock();try{while(isFull())notFull.await();// 满则等待produce();notEmpty.signal();// 生产后通知消费者}finally{lock.unlock();}// 消费者lock.lock();try{while(isEmpty())notEmpty.await();// 空则等待consume();notFull.signal();// 消费后通知生产者}finally{lock.unlock();}Object 的 wait/notify/notifyAll 只能配合单一锁而 Condition 可以有多个实现更精细的线程调度如 ArrayBlockingQueue 的实现。三、思维导图速览┌───────────────────────────────────────────────────┐ │ ReentrantLock 深度解析 │ ├───────────────────────────────────────────────────┤ │ │ │ 底层AQSAbstractQueuedSynchronizer │ │ • state同步状态int │ │ • CLH 队列双向链表存储等待线程 │ │ │ │ 可重入实现 │ │ • state 计数0→1→2... 释放时递减 │ │ • synchronized 也可重入Mark Word 记录 │ │ │ │ 公平锁 vs 非公平锁 ⭐⭐⭐⭐⭐ │ │ • 公平锁先检查队列严格按FIFO │ │ • 非公平锁直接CAS抢性能更好 │ │ │ │ 常用方法 │ │ • lock / lockInterruptibly │ │ • tryLock / tryLock(time) │ │ • unlock必须 finally │ │ │ │ Condition多条件变量 ⭐⭐⭐⭐ │ │ • 比 wait/notify 更精细 │ │ • 典型生产者-消费者notFull/notEmpty │ │ │ │ vs synchronized ⭐⭐⭐⭐⭐ │ │ • 实现JVM vs JDK │ │ • 释放自动 vs 手动 │ │ • 功能简单 vs 丰富中断/超时/公平/多Condition│ └───────────────────────────────────────────────────┘四、写在最后AQS 是 JUC 的核心骨架理解 AQS 才能理解 ReentrantLock、CountDownLatch、Semaphore 等所有并发工具后续学习 CountDownLatch 时会更容易ReentrantLock vs synchronized是面试高频对比题要能清晰说出 6-8 个对比维度lock() 必须放在 try 之外这个细节很容易被忽略手写代码时要注意

相关新闻

最新新闻

AI需求泡沫下的真实需求判断与工程落地指南

AI需求泡沫下的真实需求判断与工程落地指南

“AI需求泡沫”最近被反复提起,我的判断是:需求不是假的,泡沫也不是假的,真正的问题是大家把“技术能力有突破”和“用户需求真实存在”混在一起了。这篇内容适合正在做AI产品、想用大模型解决实际问题、或者还在犹豫要不要押注AI…

2026/8/30 5:48:02
Muon优化器在Stiefel流形上的闭式更新:从迭代近似到精确投影

Muon优化器在Stiefel流形上的闭式更新:从迭代近似到精确投影

看到Muon on the Stiefel Manifold Admits an Exact Closed-Form Update这个主题时,我第一反应是:这说的不就是给 Muon 优化器换一个更精确的正交化步骤吗?后来在一组小实验里把 Newton-Schulz 迭代换成一次 SVD 投影,我才意识到&…

2026/8/30 5:48:02
微信小程序开发实战:从基础到高效组件化架构

微信小程序开发实战:从基础到高效组件化架构

简介:本资源是一套完整的微信小程序酒水商城实战项目源码,面向前端初学者及小程序开发入门者,旨在帮助开发者系统掌握电商类小程序的核心开发流程与关键技术。压缩包共58个文件,包含9个JavaScript逻辑文件、8个WXML页面结构文件、…

2026/8/30 5:48:02
美团后端四轮面试全流程复盘:从算法到系统设计实战指南

美团后端四轮面试全流程复盘:从算法到系统设计实战指南

美团四轮面试面经,写这篇东西的时候我刚把最后一轮HR面的邮件确认收好。从投递简历到拿到意向书,前后差不多一个月,四轮面试的强度比我预想的高不少,每一轮都在筛人,不是走过场。这篇文章把我经历的完整过程、每一轮的…

2026/8/30 5:48:02
自注意力机制详解:从原理到PyTorch实现与优化

自注意力机制详解:从原理到PyTorch实现与优化

在实际深度学习项目中,真正决定一个模型能不能学好序列数据的关键点之一,是它如何处理元素之间的依赖关系。Transformer 之所以在自然语言处理、语音、图像甚至时间序列预测中全面替代传统 RNN,核心就是它把“注意力机制”用到了极致&#xf…

2026/8/30 5:48:02
第8章 数据权属确认与合规基石​​

第8章 数据权属确认与合规基石​​

某快消品集团准备将“消费者扫码数据库”纳入数据资产入表。这项资产覆盖了三年间数十亿次扫码记录,经成本法初步估值约2亿元。入表方案已通过内部初审,审计师也初步认可了估值方法。但在法务尽职调查中,一个致命的瑕疵被发现了。三年来&…

2026/8/30 5:43:02