java可重入锁通过线程身份识别(thread.currentthread())和state字段计数实现重入:同一线程多次lock时仅state++且不阻塞,unlock时state--,归零才释放锁并唤醒等待线程。

Java 可重入锁(如 ReentrantLock)允许同一个线程多次获取同一把锁,靠的是两个核心机制:**线程身份识别**和**重入计数管理**。它不是“绕过”锁检查,而是有意识地让同一线程的重复请求被快速放行——既不阻塞,也不破坏锁的排他语义。
靠 Thread.currentThread() 精准识别“自己”
每次调用 lock() 或 tryLock() 时,ReentrantLock 都会执行 Thread.currentThread(),拿到当前正在执行的 Thread 实例对象(内存地址级唯一)。只要这个对象和锁内部记录的“持有者线程”是同一个实例,就判定为重入。
- 线程名、ID、是否在同一线程池中,都不影响判断——只看
==比较结果 - 所以线程池里复用的工作线程可以正常重入;但若把锁对象传给另一个线程再调用
lock(),就会因 owner 不匹配而失败,甚至抛出IllegalMonitorStateException
用 state 字段维护重入次数
ReentrantLock 底层基于 AQS(AbstractQueuedSynchronizer),其中 state 是一个 volatile int,承担双重角色:
- 值为 0 → 锁空闲
- 值大于 0 → 锁被占用,数值等于当前线程的持有次数
首次获取锁时,state 从 0 变为 1,并记录 owner 线程;后续重入时,不修改 owner,只做 state++。释放锁时也只 state--,直到归零才真正清空 owner 并唤醒等待队列中的其他线程。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
重入时的行为表现很直接
你不需要额外配置或标记,只要满足“同一线程 + 同一把锁”,以下操作都会立即成功:
-
lock():不排队、不阻塞,直接返回 -
tryLock():立刻返回true(注意:tryLock(timeout, unit)在重入时仍可能超时,因为它会先检查同步队列头节点状态,不跳过排队逻辑) -
getHoldCount():返回当前线程对该锁的持有次数(仅对当前线程有效,其他线程调用返回 0)
必须严格配对 lock/unlock 才安全
重入机制依赖精确的计数匹配:
- 每调用一次
lock(),就必须对应一次unlock() - 少调一次 →
state始终 > 0,锁永远无法释放,其他线程永久阻塞 - 多调一次 → 抛
IllegalMonitorStateException,且已发生的减操作不会回滚
所以推荐始终用 try-finally 包裹,确保 unlock 被执行。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










