文章

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 很多同步器的基础框架。

  • 典型实现:ReentrantLockSemaphoreCountDownLatchReentrantReadWriteLock
  • 核心机制:
    • 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 进行授权