Java Lock 接口(整合版)
Java Lock 接口(整合版)
本文整合了原有的锁相关笔记(Java锁、java中的锁、锁的使用、jvm内置锁优化升级过程),统一从“概念 -> 机制 -> 实战”梳理。
1. 锁的整体认知
Java 里常见的并发控制手段:
synchronized:JVM 内置监视器锁,语法简单,自动释放。Lock(典型是ReentrantLock):可中断、可超时、可尝试获取锁,能力更灵活。ReadWriteLock:读写分离,适合读多写少场景。Condition:基于Lock的等待/通知机制,比wait/notify更可控。
2. synchronized 与 Lock 对比
2.1 共同点
- 都能实现互斥。
- 都能保证可见性。
- 都是可重入。
2.2 关键差异
synchronized语法级,锁的获取和释放由 JVM 管理。Lock代码级,通常需要try/finally手动释放。Lock支持:- 超时获取(
tryLock(timeout)) - 可中断获取(
lockInterruptibly()) - 公平/非公平策略
- 多条件队列(多个
Condition)
- 超时获取(
3. 公平锁与非公平锁
以 ReentrantLock 为例:
1
2
Lock fairLock = new ReentrantLock(true); // 公平锁
Lock unfairLock = new ReentrantLock(false); // 非公平锁(默认)
- 公平锁:按等待顺序获取锁,吞吐量通常较低。
- 非公平锁:允许插队,吞吐量更高,但可能出现线程饥饿。
4. JVM 锁优化脉络
sychronized 在 JVM 层经历了多种优化策略:
- 偏向锁
- 轻量级锁
- 重量级锁
- 自旋与自适应自旋
- 锁消除
- 锁粗化
这些优化目标一致:降低竞争不激烈场景下的加锁成本。
5. AQS 与 Lock 体系
AbstractQueuedSynchronizer(AQS)是 J.U.C 很多同步器的基础框架。
- 典型实现:
ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock - 核心机制:
volatile state记录同步状态- CLH 同步队列管理等待线程
- CAS +
LockSupport.park/unpark
6. Condition 与 wait/notify
wait/notify绑定在对象监视器上(synchronized)。Condition绑定在Lock上,可创建多个条件队列,更适合复杂协作场景。
典型能力:
await():当前线程等待并释放锁signal():唤醒一个等待线程signalAll():唤醒全部等待线程
7. 读写锁适用场景
ReentrantReadWriteLock 的核心特性:
- 读读共享
- 读写互斥
- 写写互斥
适合“读多写少”业务,如配置缓存、字典查询、元数据读取。
8. 实战建议
- 能用
synchronized且语义清晰时,优先简单方案。 - 需要超时、中断、公平策略、多条件队列时,用
ReentrantLock。 - 高并发读多写少场景可考虑读写锁。
- 所有显式锁都必须在
finally中释放。
1
2
3
4
5
6
7
8
lock.lock();
try {
// critical section
} finally {
lock.unlock();
}
相关阅读
本文由作者按照 CC BY 4.0 进行授权