Appearance
ReentrantLock 实战怎么用:可重入、tryLock、Condition 和使用边界
ReentrantLock 经常和 synchronized 一起被讨论,但很多时候大家只记住了“它更灵活”,却不一定清楚到底灵活在哪。
先说结论
ReentrantLock 最适合的场景不是“所有地方都替代 synchronized”,而是你明确需要下面这些能力时:
tryLock- 可中断获取锁
- 超时等待
- 多个条件队列
如果你只是要普通互斥,synchronized 依然非常值得优先考虑。
一、什么叫可重入
可重入的意思是:
- 同一个线程已经拿到这把锁之后,再次进入同一把锁保护的代码,不会把自己锁死
这对嵌套调用很重要。
二、ReentrantLock 最常见的几个能力
1. tryLock
可以尝试拿锁,而不是一直傻等:
java
if (lock.tryLock()) {
try {
// do something
} finally {
lock.unlock();
}
}这适合:
- 不希望线程长期阻塞
- 失败时可以走降级或兜底逻辑
2. 可中断获取
如果线程在等锁过程中允许被中断,这一点会比 synchronized 更灵活。
3. 超时等待
java
if (lock.tryLock(2, TimeUnit.SECONDS)) {
try {
// do something
} finally {
lock.unlock();
}
}适合:
- 避免长时间卡死
- 给调用链一个更清晰的超时边界
4. Condition
它可以让一把锁上挂多个等待条件,比传统 wait/notify 更清晰一些。
三、为什么它也更容易出错
因为灵活通常意味着使用成本更高。
最典型的问题就是:
- 忘记
unlock
所以几乎所有 ReentrantLock 使用都应该写成:
java
lock.lock();
try {
// business
} finally {
lock.unlock();
}四、什么时候值得用 ReentrantLock
适合
- 需要
tryLock - 需要等待超时
- 需要中断等待
- 需要多个条件队列
不一定值得
- 只是普通同步代码块
- 没有额外控制需求
- 更在乎代码简洁与稳定
五、一个常见误区
很多人会直接认为:
ReentrantLock一定比synchronized高级
其实更准确地说:
- 它只是提供了更多控制能力
如果这些能力你根本用不到,那增加的复杂度未必划算。
一句话总结
ReentrantLock 的优势不在“替代所有锁”,而在于它给了你更细的等待与唤醒控制。
用它最关键的前提不是追求“更高级”,而是你确实需要这些额外能力。