AQS 的 acquireInterruptibly 无法直接用于分布式锁,因其仅处理本地线程中断,不感知远程锁状态、网络超时或协调器释放,需同时实现本地等待控制与协调器主动清理。

为什么不能直接用 AQS 的 acquireInterruptibly 处理分布式锁
AQS 的 acquireInterruptibly 确实能响应线程中断,但它只作用于「本地线程阻塞等待」这一层。在分布式场景中,锁的持有者、等待者往往跨 JVM 甚至跨机器,AQS 根本不知道远程节点是否已宕机、网络是否超时、协调服务(如 Redis/ZooKeeper)是否已释放锁。一旦你把 ReentrantLock 拿去套分布式逻辑,acquireInterruptibly 就只是让本地线程早点从 park 状态醒来,对实际锁状态毫无影响——它既不通知远端释放锁,也不触发分布式协调器的清理动作。
真正可中断的分布式锁必须分两层控制
要让中断在分布式资源竞争中“生效”,得把中断信号同时透传到两个层面:
- 本地线程层:用
acquireInterruptibly或tryAcquireNanos避免无限挂起; - 分布式协调层:在中断发生时主动向协调器(如 Redis)发起解锁/取消请求,比如调用
DEL lock_key或 ZooKeeper 的delete,并确保该操作具备幂等性与最终一致性。
典型错误是只做第一层:线程被中断后退出了,但锁还在 Redis 里挂着,导致其他节点永远等不到它释放——这不是可中断,这是制造死锁。
tryAcquireNanos 在分布式锁中的真实用途不是“抢锁”,而是“设超时边界”
很多人误以为 tryAcquireNanos 能帮你自动完成分布式重试或清理,其实它只是 AQS 内部的一个带纳秒精度的自旋+park 控制逻辑。在封装分布式锁时,它的正确用法是:
- 作为本地等待策略的兜底:比如你封装了一个基于 Redis 的
RedisLock,其lock()方法内部调用tryAcquireNanos来控制“最多在本地循环等待多久”,而不是指望它连 Redis 都能超时; - 配合
Thread.interrupted()做快速退出分支:在每次尝试 SETNX 失败后检查中断状态,避免继续发无意义的网络请求; - 注意
nanosTimeout是本地计时,受系统时钟漂移和 GC 暂停影响,不能替代 Redis 的EXPIRE过期时间。
示例片段(伪代码):
interrupt()










