前言

面试和实际编码里 java 锁都是绕不开的话题。这篇先按维度把常见锁的分类理清楚,再聚焦 ReentrantLock:它的四个高级特性分别解决 synchronized 的什么短板,配可运行的验证代码,最后是核心方法与注意事项。

一、java 常见锁的七种分类

按不同维度,锁可以分成下面几组——同一把锁在不同维度下有不同名字:

维度 分类 说明
竞争是否排队 公平锁 / 非公平锁 synchronized 和 ReentrantLock 默认都是非公平锁,非公平可以避免线程唤醒的空档期、提高吞吐
同线程能否重复获取 可重入锁 / 不可重入锁 ReentrantLock 对同一线程可重入,不会自己锁死自己
能否被多线程共享 共享锁 / 独占锁 ReentrantReadWriteLock 中读锁是共享锁、写锁是排他锁
等待期能否被中断 可中断锁 / 不可中断锁 ReentrantLock 的 lockInterruptibly() 支持中断
是否锁住资源 悲观锁 / 乐观锁 synchronized 是悲观;CAS(如 Atomic 系列)是乐观
等待方式 自旋锁 / 阻塞锁 自旋避免上下文切换,但空耗 CPU
- 偏向锁/轻量级锁/重量级锁 synchronized 的锁升级路径(JDK 15 起偏向锁已废弃)

二、ReentrantLock 的四个高级特性

ReentrantLock 实现了 Lock 接口,作用与 synchronized 一样是线程安全,但多了四个 synchronized 没有的能力。

……

阅读全文