19 ReentrantLock和synchronized在现代jvm差别有多大?

vvEcho 2026-01-27 17:49:16
Categories: Tags:

特点对比

synchronized(内置锁)是java内置关键字,用在synchronized修饰的代码块或者方法中,会自动获取对象锁,并释放对象锁。
它的特点如下:

ReentrantLock(显式锁),是jdk1.5之后出现的,是一个可重入锁,它提供了比synchronized更细粒度的控制,并且提供了更多的功能。
它的特点如下:

使用场景对比

synchronized(内置锁)适用于简单的同步场景,适用于大多数常规业务场景,与wait/notify配合使用时

reentrantlock(显式锁)适用于更复杂的同步场景,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 需要高级功能时
if (lock.tryLock(100, TimeUnit.MILLISECONDS)) {
try {
// 带超时的锁获取
} finally {
lock.unlock();
}
}

// 需要可中断锁
lock.lockInterruptibly();

// 复杂条件等待
Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();

reentrantlock提供一些方法获取线程的信息,而synchronized没有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ReentrantLock lock = new ReentrantLock();

// 1. 获取等待队列长度
int queueLength = lock.getQueueLength(); // 等待锁的线程数(估计值)

// 2. 检查是否有线程在等待
boolean hasQueuedThreads = lock.hasQueuedThreads();

// 3. 检查特定线程是否在等待
boolean threadIsQueued = lock.hasQueuedThread(Thread.currentThread());

// 4. 检查锁是否被持有
boolean isLocked = lock.isLocked();

// 5. 检查当前线程是否持有锁
boolean isHeldByCurrentThread = lock.isHeldByCurrentThread();

// 6. 获取持有计数(重入次数)
int holdCount = lock.getHoldCount(); // 只能在持有锁的线程中调用

// 7. 检查是否为公平锁
boolean isFair = lock.isFair();