JDK 8 ReentrantLock 源码详解(详细注释版)
1. 类定义和基本属性
public class ReentrantLock implements Lock, java.io.Serializable {
// 序列化版本号
private static final long serialVersionUID = 7373984872572414699L;
/**
* ReentrantLock的核心同步器
* 使用组合模式,将同步控制委托给内部的Sync对象
* 这样可以支持不同的同步策略(公平和非公平)
*/
private final Sync sync;
/**
* 同步器抽象基类
* 继承自AbstractQueuedSynchronizer(AQS)
* 提供了锁的基本功能和可重入性支持
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
* 抽象方法:获取锁的策略
* 公平锁和非公平锁有不同的实现
*/
abstract void lock();
/**
* 非公平方式尝试获取锁
* 这是ReentrantLock的核心实现
* @param acquires 获取许可数(通常为1)
* @return 如果获取成功返回true,否则返回false
*
* 获取过程:
* 1. 使用CAS操作尝试将state从0设置为1
* 2. 如果成功,设置当前线程为独占线程
* 3. 如果失败,说明锁已被其他线程持有
*/
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread(); // 获取当前线程
int c = getState(); // 获取当前锁的状态(state字段)
// 如果state为0,说明锁未被持有
if (c == 0) {
// 使用CAS操作尝试获取锁
// compareAndSetState(0, 1)尝试将state从0原子性地设置为1
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); // 更新state
return true; // 返回获取成功
}
return false; // 获取失败
}
/**
* 尝试释放锁
* @param releases 释放许可数(通常为1)
* @return 如果完全释放返回true,否则返回false
*
* 释放过程:
* 1. 减少重入次数
* 2. 如果重入次数为0,完全释放锁
* 3. 唤醒等待队列中的下一个线程
*/
protected final boolean tryRelease(int releases) {
int c = getState() - releases; // 减少重入次数
// 检查当前线程是否是锁的持有者
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
// 如果重入次数为0,说明完全释放锁
if (c == 0) {
free = true; // 标记为完全释放
setExclusiveOwnerThread(null); // 清除独占线程
}
setState(c); // 更新state
return free; // 返回是否完全释放
}
/**
* 判断当前线程是否持有锁
* @return 如果当前线程持有锁返回true,否则返回false
*/
protected final boolean isHeldExclusively() {
// 通过比较当前线程和独占线程来判断
return getExclusiveOwnerThread() == Thread.currentThread();
}
/**
* 创建条件对象
* @return 新的Condition实例
*/
final ConditionObject newCondition() {
return new ConditionObject();
}
/**
* 获取当前持有锁的线程
* @return 持有锁的线程,如果未被持有则返回null
*/
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
/**
* 获取锁的重入次数
* @return 重入次数
*/
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
/**
* 判断锁是否被持有
* @return 如果被持有返回true,否则返回false
*/
final boolean isLocked() {
return getState() != 0;
}
/**
* 自定义序列化读取方法
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // 重置state为0
}
}
/**
* 非公平锁实现
* 允许插队,性能更好但可能导致线程饥饿
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* 获取锁(非公平方式)
* 直接尝试获取,不管是否有线程在等待
*/
final void lock() {
// 直接尝试CAS获取锁,不检查等待队列
if (compareAndSetState(0, 1))
// 获取成功,设置当前线程为独占线程
setExclusiveOwnerThread(Thread.currentThread());
else
// 获取失败,调用AQS的acquire方法进入等待队列
acquire(1);
}
/**
* 尝试获取锁
* @param acquires 获取许可数
* @return 如果获取成功返回true,否则返回false
*/
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
/**
* 公平锁实现
* 按照等待顺序获取锁,避免线程饥饿
*/
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
/**
* 获取锁(公平方式)
* 必须检查是否有线程在等待队列中
*/
final void lock() {
// 直接调用AQS的acquire方法,会检查等待队列
acquire(1);
}
/**
* 尝试获取锁(公平方式)
* @param acquires 获取许可数
* @return 如果获取成功返回true,否则返回false
*
* 公平获取过程:
* 1. 检查是否有前驱节点(确保公平性)
* 2. 如果没有前驱节点,尝试CAS获取
* 3. 如果获取成功,设置独占线程
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread(); // 获取当前线程
int c = getState(); // 获取当前锁状态
// 如果锁未被持有
if (c == 0) {
// hasQueuedPredecessors()检查是否有前驱节点
// 如果没有前驱节点且CAS成功,则获取锁
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 如果当前线程已经是锁的持有者(可重入)
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires; // 增加重入次数
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc); // 更新state
return true;
}
return false; // 获取失败
}
}
2. 构造方法(详细注释)
/**
* 默认构造方法
* 创建一个非公平的ReentrantLock
* 非公平锁性能更好,但可能导致线程饥饿
*
* 构造过程:
* 1. 创建NonfairSync实例
* 2. 设置为sync字段
* 3. 准备好锁的基本功能
*/
public ReentrantLock() {
sync = new NonfairSync(); // 默认使用非公平锁
}
/**
* 指定公平策略的构造方法
* @param fair 是否使用公平锁
*
* 公平性说明:
* - 公平锁:按照请求锁的顺序获得锁,避免饥饿
* - 非公平锁:允许插队,性能更好但可能导致某些线程长时间等待
*
* 选择建议:
* - 高并发场景:使用非公平锁(默认)
* - 需要避免饥饿:使用公平锁
* - 对性能要求极高:使用非公平锁
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync(); // 根据参数选择同步器
}
3. 核心锁操作方法(详细注释)
/**
* 获取锁
* 如果锁不可用,当前线程会阻塞直到获取锁
*
* 获取过程:
* 1. 尝试直接获取锁
* 2. 如果获取失败,加入等待队列
* 3. 阻塞当前线程直到被唤醒
* 4. 被唤醒后重新尝试获取锁
*
* 可重入性:
* - 同一线程可以多次获取锁
* - 每次获取都会增加重入计数
* - 每次释放都会减少重入计数
* - 只有当重入计数为0时,锁才真正释放
*
* 中断处理:
* - 此方法不响应中断
* - 即使线程被中断也会继续等待
*/
public void lock() {
sync.lock(); // 委托给sync的lock方法
}
/**
* 获取锁(可中断)
* 如果锁不可用,当前线程会阻塞直到获取锁
* 与lock()不同的是,此方法响应中断
*
* 中断处理:
* - 如果线程在等待过程中被中断,会抛出InterruptedException
* - 线程可以被优雅地中止
*
* @throws InterruptedException 如果线程被中断
*/
public void lockInterruptibly() throws InterruptedException {
// 调用AQS的acquireInterruptibly方法
sync.acquireInterruptibly(1);
}
/**
* 尝试获取锁(非阻塞)
* 立即返回,不会阻塞当前线程
*
* 获取结果:
* - 如果锁可用,立即获取并返回true
* - 如果锁不可用,立即返回false
*
* 使用场景:
* - 避免线程阻塞
* - 实现超时控制
* - 检查锁的状态
*
* @return 如果获取成功返回true,否则返回false
*/
public boolean tryLock() {
// 调用sync的nonfairTryAcquire方法
return sync.nonfairTryAcquire(1);
}
/**
* 尝试获取锁(带超时)
* 如果锁不可用,等待指定时间
*
* 超时处理:
* - 在指定时间内获取锁,返回true
* - 超时未获取到锁,返回false
* - 等待过程中可被中断
*
* @param timeout 等待时间
* @param unit 时间单位
* @return 如果获取成功返回true,否则返回false
* @throws InterruptedException 如果线程被中断
*/
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
// 调用AQS的tryAcquireNanos方法
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
/**
* 释放锁
* 减少重入计数,如果为0则完全释放锁
*
* 释放过程:
* 1. 减少重入计数
* 2. 如果计数为0,唤醒等待队列中的线程
* 3. 允许下一个线程获取锁
*
* 异常处理:
* - 如果当前线程不是锁的持有者,抛出IllegalMonitorStateException
*/
public void unlock() {
// 调用sync的release方法
sync.release(1);
}
/**
* 创建新的Condition实例
* Condition提供了比内置监视器更灵活的线程等待/通知机制
*
* Condition特点:
* - 与特定的Lock实例绑定
* - 支持多个等待条件
* - 更精确的控制(signal vs signalAll)
* - 更好的性能
*
* @return 新的Condition实例
* @throws UnsupportedOperationException 如果不支持此操作
*/
public Condition newCondition() {
return sync.newCondition();
}
4. 查询和状态方法(详细注释)
/**
* 查询当前线程持有锁的次数
* 返回当前线程重入该锁的次数
*
* 查询结果:
* - 如果当前线程持有锁,返回重入次数
* - 如果当前线程未持有锁,返回0
*
* 使用场景:
* - 调试和监控
* - 实现复杂的同步逻辑
* - 避免重复获取锁
*
* @return 重入次数
*/
public int getHoldCount() {
return sync.getHoldCount();
}
/**
* 判断当前线程是否持有锁
* 这是查询方法,不会阻塞
*
* 查询结果:
* - 如果当前线程持有锁返回true
* - 否则返回false
*
* 与getHoldCount的区别:
* - isHeldByCurrentThread()返回boolean
* - getHoldCount()返回具体次数
*
* @return 如果当前线程持有锁返回true,否则返回false
*/
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
/**
* 判断锁是否被任何线程持有
* 这是全局状态查询
*
* 查询结果:
* - 如果锁被持有返回true
* - 如果锁空闲返回false
*
* 使用场景:
* - 监控锁的使用情况
* - 实现复杂的同步逻辑
* - 调试和诊断
*
* @return 如果锁被持有返回true,否则返回false
*/
public boolean isLocked() {
return sync.isLocked();
}
/**
* 判断锁是否是公平锁
*
* 查询结果:
* - 如果是公平锁返回true
* - 如果是非公平锁返回false
*
* 设计考虑:
* - 通过检查sync的类型来判断
* - FairSync类型表示公平锁
* - NonfairSync类型表示非公平锁
*
* @return 如果是公平锁返回true,否则返回false
*/
public final boolean isFair() {
return sync instanceof FairSync;
}
/**
* 获取当前持有锁的线程
*
* 查询结果:
* - 如果锁被持有,返回持有线程
* - 如果锁空闲,返回null
*
* 使用场景:
* - 调试和监控
* - 实现诊断工具
* - 分析死锁情况
*
* @return 持有锁的线程,如果锁空闲返回null
*/
protected Thread getOwner() {
return sync.getOwner();
}
/**
* 查询是否有线程正在等待获取锁
* 检查AQS的同步队列
*
* 查询结果:
* - 如果有等待线程返回true
* - 如果没有等待线程返回false
*
* 使用场景:
* - 监控锁的竞争情况
* - 实现负载均衡
* - 优化系统性能
*
* @return 如果有等待线程返回true,否则返回false
*/
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
/**
* 查询指定线程是否正在等待获取锁
*
* 查询结果:
* - 如果指定线程在等待队列中返回true
* - 否则返回false
*
* 使用场景:
* - 调试和诊断
* - 实现复杂的同步逻辑
* - 分析线程状态
*
* @param thread 要查询的线程
* @return 如果线程在等待队列中返回true,否则返回false
*/
public final boolean hasQueuedThread(Thread thread) {
return sync.isQueued(thread);
}
/**
* 获取等待获取锁的线程数量
*
* 查询结果:
* - 返回等待队列中的线程数量
* - 这是一个估算值,因为线程状态可能随时变化
*
* 使用场景:
* - 监控锁的竞争程度
* - 实现负载监控
* - 性能调优
*
* @return 等待线程数量
*/
public final int getQueueLength() {
return sync.getQueueLength();
}
/**
* 获取等待获取锁的线程集合
*
* 查询结果:
* - 返回等待队列中线程的集合
* - 集合是线程安全的快照
*
* 使用场景:
* - 调试和诊断
* - 实现管理工具
* - 分析系统状态
*
* @return 等待线程集合
*/
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
5. Condition相关方法(详细注释)
/**
* 查询是否有线程在等待指定的Condition
*
* 查询结果:
* - 如果有线程在等待返回true
* - 否则返回false
*
* 使用场景:
* - 监控Condition的使用情况
* - 实现复杂的同步逻辑
* - 调试和诊断
*
* @param condition 要查询的Condition
* @return 如果有线程在等待返回true,否则返回false
* @throws IllegalArgumentException 如果condition不是由此锁创建的
*/
public boolean hasWaiters(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
/**
* 获取在指定Condition上等待的线程数量
*
* 查询结果:
* - 返回等待Condition的线程数量
* - 这是一个估算值
*
* 使用场景:
* - 监控Condition的使用情况
* - 实现负载监控
* - 性能调优
*
* @param condition 要查询的Condition
* @return 等待线程数量
* @throws IllegalArgumentException 如果condition不是由此锁创建的
*/
public int getWaitQueueLength(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
/**
* 获取在指定Condition上等待的线程集合
*
* 查询结果:
* - 返回等待Condition的线程集合
* - 集合是线程安全的快照
*
* 使用场景:
* - 调试和诊断
* - 实现管理工具
* - 分析系统状态
*
* @param condition 要查询的Condition
* @return 等待线程集合
* @throws IllegalArgumentException 如果condition不是由此锁创建的
*/
protected Collection<Thread> getWaitingThreads(Condition condition) {
if (condition == null)
throw new NullPointerException();
if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
throw new IllegalArgumentException("not owner");
return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}
6. ReentrantLock 的特点分析
核心设计理念:
/**
* ReentrantLock的核心设计思想:
*
* 1. 委托模式:
* - 使用组合而非继承
* - 将同步控制委托给内部的Sync对象
* - 支持不同的同步策略(公平/非公平)
*
* 2. AQS集成:
* - 继承AbstractQueuedSynchronizer
* - 复用成熟的队列管理机制
* - 提供完整的同步框架
*
* 3. 可重入性:
* - 支持同一线程多次获取锁
* - 通过state字段记录重入次数
* - 完全释放时才允许其他线程获取
*
* 4. 公平性选择:
* - 提供公平和非公平两种模式
* - 公平锁避免线程饥饿
* - 非公平锁提高性能
*
* 5. Condition支持:
* - 提供比内置监视器更灵活的条件等待
* - 支持多个等待条件
* - 更精确的线程控制
*
* 6. 丰富的查询API:
* - 提供详细的锁状态信息
* - 支持监控和诊断
* - 便于调试和性能调优
*
* 适用场景:
* - 需要比synchronized更灵活的锁控制
* - 需要可中断的锁获取
* - 需要超时控制的锁获取
* - 需要公平锁避免线程饥饿
* - 需要复杂的线程等待/通知机制
*/
性能特征分析:
/**
* ReentrantLock的性能特征:
*
* 获取锁时间复杂度:
* - 无竞争:O(1) - 直接CAS操作
* - 有竞争:O(1) 平均,O(n) 最坏(等待队列长度)
*
* 释放锁时间复杂度:
* - O(1) - 更新state并唤醒等待线程
*
* 内存复杂度:
* - O(1) 基本开销
* - O(n) 等待队列开销(n为等待线程数)
*
* 并发特性:
* - 完全线程安全
* - 支持高并发读写
* - 无锁设计(通过CAS和AQS)
* - 可重入性保证
*
* 公平性对比:
* - 非公平锁:吞吐量更高,可能有线程饥饿
* - 公平锁:避免饥饿,吞吐量略低
*
* 与synchronized对比:
* - 功能更丰富(可中断、超时、公平性)
* - 性能相当或更好(JDK 1.6后优化)
* - 更好的可监控性
* - 更灵活的使用方式
*
* 内存使用:
* - 每个实例固定开销较小
* - 等待线程会增加内存使用
* - 及时GC,避免内存泄漏
*/
7. 使用示例和最佳实践
/**
* 使用示例:
*
* // 基本使用
* ReentrantLock lock = new ReentrantLock();
*
* // 保护临界区
* lock.lock();
* try {
* // 临界区代码
* // 可以安全地访问共享资源
* } finally {
* lock.unlock(); // 必须在finally块中释放锁
* }
*
* // 可中断的锁获取
* try {
* lock.lockInterruptibly();
* try {
* // 临界区代码
* } finally {
* lock.unlock();
* }
* } catch (InterruptedException e) {
* // 处理中断
* Thread.currentThread().interrupt(); // 恢复中断状态
* }
*
* // 带超时的锁获取
* try {
* if (lock.tryLock(5, TimeUnit.SECONDS)) {
* try {
* // 临界区代码
* } finally {
* lock.unlock();
* }
* } else {
* // 获取锁超时,处理超时情况
* System.out.println("Failed to acquire lock within timeout");
* }
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
*
* // 非公平锁(默认)
* ReentrantLock nonfairLock = new ReentrantLock();
*
* // 公平锁
* ReentrantLock fairLock = new ReentrantLock(true);
*
* // 使用Condition
* Condition condition = lock.newCondition();
*
* // 等待条件
* lock.lock();
* try {
* while (!conditionMet()) {
* condition.await(); // 等待条件满足
* }
* // 条件满足后的处理
* } finally {
* lock.unlock();
* }
*
* // 通知等待的线程
* lock.lock();
* try {
* // 改变条件
* setConditionMet(true);
* condition.signal(); // 或者 condition.signalAll();
* } finally {
* lock.unlock();
* }
*
* 最佳实践:
*
* 1. 正确的锁获取和释放:
* ReentrantLock lock = new ReentrantLock();
* lock.lock();
* try {
* // 临界区代码
* // 可能抛出异常的操作
* } finally {
* lock.unlock(); // 确保锁总是被释放
* }
*
* 2. 使用可中断的锁获取:
* try {
* lock.lockInterruptibly();
* try {
* // 临界区代码
* } finally {
* lock.unlock();
* }
* } catch (InterruptedException e) {
* // 处理中断,通常是恢复中断状态
* Thread.currentThread().interrupt();
* }
*
* 3. 设置合理的超时时间:
* try {
* if (lock.tryLock(10, TimeUnit.SECONDS)) {
* try {
* // 临界区代码
* } finally {
* lock.unlock();
* }
* } else {
* // 超时处理
* System.out.println("Operation timed out");
* }
* } catch (InterruptedException e) {
* Thread.currentThread().interrupt();
* }
*
* 4. 选择合适的公平性:
* // 高并发场景使用非公平锁(默认)
* ReentrantLock lock = new ReentrantLock();
*
* // 需要避免饥饿时使用公平锁
* ReentrantLock fairLock = new ReentrantLock(true);
*
* 5. 合理使用Condition:
* private final ReentrantLock lock = new ReentrantLock();
* private final Condition notFull = lock.newCondition();
* private final Condition notEmpty = lock.newCondition();
*
* // 生产者
* public void put(Object item) throws InterruptedException {
* lock.lock();
* try {
* while (isFull()) {
* notFull.await(); // 等待空间
* }
* // 添加元素
* notEmpty.signal(); // 通知消费者
* } finally {
* lock.unlock();
* }
* }
*
* // 消费者
* public Object take() throws InterruptedException {
* lock.lock();
* try {
* while (isEmpty()) {
* notEmpty.await(); // 等待元素
* }
* Object item = remove(); // 移除元素
* notFull.signal(); // 通知生产者
* return item;
* } finally {
* lock.unlock();
* }
* }
*
* 6. 监控锁的使用情况:
* ReentrantLock lock = new ReentrantLock();
*
* // 检查锁的状态
* if (lock.isLocked()) {
* System.out.println("Lock is currently held");
* }
*
* if (lock.isHeldByCurrentThread()) {
* System.out.println("Current thread holds the lock");
* System.out.println("Hold count: " + lock.getHoldCount());
* }
*
* // 检查等待队列
* if (lock.hasQueuedThreads()) {
* System.out.println("Threads waiting for lock: " + lock.getQueueLength());
* }
*
* 7. 避免死锁:
* // 确保锁的获取顺序一致
* private final ReentrantLock lock1 = new ReentrantLock();
* private final ReentrantLock lock2 = new ReentrantLock();
*
* public void method1() {
* lock1.lock();
* try {
* lock2.lock();
* try {
* // 业务逻辑
* } finally {
* lock2.unlock();
* }
* } finally {
* lock1.unlock();
* }
* }
*
* public void method2() {
* lock1.lock(); // 保持相同的获取顺序
* try {
* lock2.lock();
* try {
* // 业务逻辑
* } finally {
* lock2.unlock();
* }
* } finally {
* lock1.unlock();
* }
* }
*
* 8. 处理可重入性:
* private final ReentrantLock lock = new ReentrantLock();
*
* public void outerMethod() {
* lock.lock();
* try {
* innerMethod(); // 同一线程可以再次获取锁
* } finally {
* lock.unlock(); // 只需要一次unlock
* }
* }
*
* public void innerMethod() {
* lock.lock();
* try {
* // 业务逻辑
* System.out.println("Hold count: " + lock.getHoldCount());
* } finally {
* lock.unlock();
* }
* }
*
* 9. 异常处理:
* ReentrantLock lock = new ReentrantLock();
* lock.lock();
* try {
* // 可能抛出异常的代码
* riskyOperation();
* } catch (Exception e) {
* // 处理异常
* System.err.println("Error occurred: " + e.getMessage());
* throw e; // 重新抛出或处理
* } finally {
* lock.unlock(); // 确保锁被释放
* }
*
* 10. 性能调优:
* // 在高并发场景下监控性能
* ReentrantLock lock = new ReentrantLock();
*
* // 定期检查锁的使用情况
* if (lock.getQueueLength() > 100) {
* System.out.println("High contention detected");
* // 可能需要优化锁的粒度
* }
*/
8. 与其他同步机制的比较
/**
* ReentrantLock vs synchronized vs ReadWriteLock:
*
* ReentrantLock:
* - 可中断的锁获取
* - 可超时的锁获取
* - 公平性选择
* - Condition支持
* - 丰富的监控API
* - 需要手动释放锁
*
* synchronized:
* - 自动释放锁
* - JVM优化(偏向锁、轻量级锁等)
* - 语法简洁
* - 不支持中断和超时
* - 不支持公平性选择
* - 功能相对简单
*
* ReadWriteLock:
* - 读写分离
* - 多个读线程可以同时访问
* - 写线程独占访问
* - 适合读多写少的场景
* - ReentrantReadWriteLock是其实现
*
* StampedLock:
* - JDK 8新增
* - 更高性能的读写锁
* - 支持乐观读
* - 不支持重入
* - 更复杂的使用方式
*
* 选择建议:
* - 简单同步需求:synchronized
* - 需要中断/超时:ReentrantLock
* - 读多写少:ReadWriteLock
* - 高性能读操作:StampedLock
* - 复杂同步逻辑:ReentrantLock
*
* 性能对比:
* - 无竞争:synchronized ≈ ReentrantLock
* - 有竞争:ReentrantLock ≥ synchronized(JDK 1.6后)
* - 读多写少:ReadWriteLock > ReentrantLock > synchronized
* - 高并发读:StampedLock > ReadWriteLock
*/
9. 总结
ReentrantLock 的核心特性:
-
可重入性:
- 同一线程可以多次获取锁
- 通过state字段记录重入次数
- 完全释放时才允许其他线程获取
-
灵活性:
- 支持可中断的锁获取
- 支持超时控制
- 提供公平和非公平两种模式
- 支持Condition条件等待
-
高性能:
- 基于AQS实现,性能优秀
- 无竞争时使用CAS操作
- 有竞争时使用队列管理
-
丰富的API:
- 提供详细的锁状态查询
- 支持监控和诊断
- 便于调试和性能调优
-
线程安全:
- 所有操作都是线程安全的
- 支持高并发环境
- 无锁设计保证性能
适用场景:
- 需要比synchronized更灵活的锁控制
- 需要可中断的锁获取
- 需要超时控制的锁获取
- 需要公平锁避免线程饥饿
- 需要复杂的线程等待/通知机制
- 高并发的同步需求
注意事项:
- 必须在finally块中释放锁
- 避免死锁(保持锁的获取顺序)
- 合理选择公平性策略
- 正确处理中断异常
- 监控锁的使用情况
- 避免长时间持有锁
性能优化建议:
- 根据业务需求选择合适的锁类型
- 合理设置超时时间
- 使用公平锁避免线程饥饿
- 监控锁的竞争情况
- 优化临界区代码减少持有时间
- 考虑使用更细粒度的锁
- 定期分析和调优锁的使用

165

被折叠的 条评论
为什么被折叠?



