java锁体系与ReentrantLock详解
前言
面试和实际编码里 java 锁都是绕不开的话题。这篇先按维度把常见锁的分类理清楚,再聚焦 ReentrantLock:它的四个高级特性分别解决 synchronized 的什么短板,配可运行的验证代码,最后是核心方法与注意事项。
一、java 常见锁的七种分类
按不同维度,锁可以分成下面几组——同一把锁在不同维度下有不同名字:
| 维度 | 分类 | 说明 |
|---|---|---|
| 竞争是否排队 | 公平锁 / 非公平锁 | synchronized 和 ReentrantLock 默认都是非公平锁,非公平可以避免线程唤醒的空档期、提高吞吐 |
| 同线程能否重复获取 | 可重入锁 / 不可重入锁 | ReentrantLock 对同一线程可重入,不会自己锁死自己 |
| 能否被多线程共享 | 共享锁 / 独占锁 | ReentrantReadWriteLock 中读锁是共享锁、写锁是排他锁 |
| 等待期能否被中断 | 可中断锁 / 不可中断锁 | ReentrantLock 的 lockInterruptibly() 支持中断 |
| 是否锁住资源 | 悲观锁 / 乐观锁 | synchronized 是悲观;CAS(如 Atomic 系列)是乐观 |
| 等待方式 | 自旋锁 / 阻塞锁 | 自旋避免上下文切换,但空耗 CPU |
| - | 偏向锁/轻量级锁/重量级锁 | synchronized 的锁升级路径(JDK 15 起偏向锁已废弃) |
二、ReentrantLock 的四个高级特性
ReentrantLock 实现了 Lock 接口,作用与 synchronized 一样是线程安全,但多了四个 synchronized 没有的能力。
……