ReentrantLock 通过 AQS 的 volatile state 状态控制、CAS 原子操作、FIFO 同步队列调度及 try-finally 必须释放机制,保障可重入、公平/非公平选择、中断响应与超时等待,确保临界区互斥与数据一致性。

ReentrantLock 通过显式加锁、状态控制和队列调度,在多线程争抢中确保同一时刻只有一个线程能进入临界区,从而避免竞态条件,保障数据一致性。
靠 AQS 实现原子状态变更
ReentrantLock 底层基于 AbstractQueuedSynchronizer(AQS),用一个 volatile int state 字段表示锁状态:
- state = 0:锁空闲,可被任意线程 CAS 设置为 1 并获取锁
- state > 0:锁已被持有;同一线程重入时 state 自增,保证可重入性
- CAS 操作是 CPU 级原子指令,不存在“读-改-写”中间态,天然防丢失更新
用 FIFO 同步队列管理等待线程
当锁被占用,后续线程不会忙等,而是被封装为 Node 加入 CLH 变体的双向同步队列:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 新线程插入队尾,前驱节点负责唤醒它,避免无序争抢
- 公平模式下严格按入队顺序分配锁;非公平模式允许插队(默认),兼顾吞吐与响应
- 队列机制让线程挂起/唤醒由 JVM 控制,比自旋更省资源,也避免了 synchronized 的“唤醒随机性”问题
必须配合 try-finally 正确释放
一致性不仅依赖加锁,更依赖锁的确定性释放:
立即学习“Java免费学习笔记(深入)”;
- lock() 成功后,必须在 finally 块中调用 unlock(),否则锁永远不释放,导致死锁或线程饥饿
- unlock() 会将 state 减 1,若减到 0,则唤醒同步队列首节点,把锁交给下一个线程
- 不写 finally 或漏掉 unlock 是最常见的实际错误,直接破坏一致性保障
支持中断与超时,避免无限阻塞
相比 synchronized,ReentrantLock 提供更可控的等待行为:
- lockInterruptibly():线程在等待锁时可响应 interrupt,主动退出争抢
- tryLock(long, TimeUnit):最多等待指定时间,超时返回 false,避免因某个线程异常卡死而拖垮整体
- 这些能力让系统在异常场景下仍能维持可用性,间接支撑了数据操作的终态一致性

















