JDK 8 ReentrantLock 源码详解(详细注释版)

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 的核心特性:

  1. 可重入性

    • 同一线程可以多次获取锁
    • 通过state字段记录重入次数
    • 完全释放时才允许其他线程获取
  2. 灵活性

    • 支持可中断的锁获取
    • 支持超时控制
    • 提供公平和非公平两种模式
    • 支持Condition条件等待
  3. 高性能

    • 基于AQS实现,性能优秀
    • 无竞争时使用CAS操作
    • 有竞争时使用队列管理
  4. 丰富的API

    • 提供详细的锁状态查询
    • 支持监控和诊断
    • 便于调试和性能调优
  5. 线程安全

    • 所有操作都是线程安全的
    • 支持高并发环境
    • 无锁设计保证性能

适用场景:

  • 需要比synchronized更灵活的锁控制
  • 需要可中断的锁获取
  • 需要超时控制的锁获取
  • 需要公平锁避免线程饥饿
  • 需要复杂的线程等待/通知机制
  • 高并发的同步需求

注意事项:

  • 必须在finally块中释放锁
  • 避免死锁(保持锁的获取顺序)
  • 合理选择公平性策略
  • 正确处理中断异常
  • 监控锁的使用情况
  • 避免长时间持有锁

性能优化建议:

  1. 根据业务需求选择合适的锁类型
  2. 合理设置超时时间
  3. 使用公平锁避免线程饥饿
  4. 监控锁的竞争情况
  5. 优化临界区代码减少持有时间
  6. 考虑使用更细粒度的锁
  7. 定期分析和调优锁的使用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值