1. ReentrantLock锁的核心价值与应用场景
在Java多线程编程中,锁机制是保证线程安全的基石。相比传统的synchronized关键字,ReentrantLock提供了更灵活、更强大的线程控制能力。我第一次在生产环境使用ReentrantLock是在一个高并发的订单处理系统中,当时synchronized已经无法满足复杂的锁超时和中断需求。
ReentrantLock属于java.util.concurrent.locks包下的显式锁,它的核心特点包括:
- 可重入性:线程可以重复获取已经持有的锁
- 公平性选择:支持公平锁和非公平锁两种模式
- 锁等待可中断:支持lockInterruptibly()方法
- 尝试获取锁:提供tryLock()方法
- 条件变量:支持多个Condition对象
重要提示:虽然ReentrantLock功能强大,但必须手动释放锁,否则会导致死锁。建议始终在finally块中释放锁。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ReentrantLock底层实现原理剖析
2.1 AQS同步器架构
ReentrantLock的核心是基于AbstractQueuedSynchronizer(AQS)实现的。AQS使用一个volatile int类型的state变量来表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。
java复制// ReentrantLock中同步器的简化实现
abstract static class Sync extends AbstractQueuedSynchronizer {
final boolean nonfairTryAcquire(int acquires) {
// 获取当前线程
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
2.2 公平锁与非公平锁差异
ReentrantLock在构造时可以指定公平策略:
java复制// 非公平锁(默认)
ReentrantLock lock = new ReentrantLock();
// 公平锁
ReentrantLock fairLock = new ReentrantLock(true);
公平锁与非公平锁的核心区别在于获取锁时的行为:
- 公平锁:严格按照FIFO顺序获取锁
- 非公平锁:允许插队,可能造成线程饥饿但吞吐量更高
在实际性能测试中,非公平锁的吞吐量通常比公平锁高出1-2个数量级,这也是默认采用非公平策略的原因。
