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

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

1. 类定义和基本属性

public class ReentrantReadWriteLock
        implements ReadWriteLock, java.io.Serializable {
    
    // 序列化版本号
    private static final long serialVersionUID = -6992448646407690164L;

    /**
     * 读锁实例
     * 提供共享访问模式
     */
    private final ReentrantReadWriteLock.ReadLock readerLock;

    /**
     * 写锁实例
     * 提供独占访问模式
     */
    private final ReentrantReadWriteLock.WriteLock writerLock;

    /**
     * 同步器,ReentrantReadWriteLock的核心实现
     * 继承自AQS,管理读写锁的状态
     */
    final Sync sync;

    /**
     * 默认构造方法
     * 创建一个非公平的ReentrantReadWriteLock
     * 
     * 构造过程:
     * 1. 创建Sync实例(默认非公平)
     * 2. 创建读锁和写锁实例
     * 3. 建立完整的读写锁体系
     */
    public ReentrantReadWriteLock() {
        this(false); // 默认使用非公平锁
    }

    /**
     * 指定公平策略的构造方法
     * @param fair 是否使用公平锁
     * 
     * 公平性说明:
     * - 公平锁:按照请求锁的顺序获得锁
     * - 非公平锁:允许插队,性能更好
     * - 读锁和写锁共享同一个公平性设置
     */
    public ReentrantReadWriteLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
        readerLock = new ReadLock(this);
        writerLock = new WriteLock(this);
    }

    /**
     * 获取读锁
     * @return 读锁实例
     */
    public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }

    /**
     * 获取写锁
     * @return 写锁实例
     */
    public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }

    /**
     * 同步器抽象基类
     * 继承自AbstractQueuedSynchronizer
     * 管理读写锁的复杂状态
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 6317671515068378041L;

        /**
         * 状态字段的位数定义
         * 
         * 状态字段(state)被分为两部分:
         * - 高16位:读锁计数(共享锁)
         * - 低16位:写锁计数(独占锁)
         * 
         * 这种设计允许同时跟踪读锁和写锁的状态
         */
        static final int SHARED_SHIFT   = 16;           // 共享锁位移量
        static final int SHARED_UNIT    = (1 << SHARED_SHIFT); // 共享锁单位值
        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1; // 最大计数值
        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; // 独占锁掩码

        /**
         * 从状态字段中提取读锁计数
         * 通过无符号右移获取高16位
         * @param c 状态值
         * @return 读锁计数
         */
        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }

        /**
         * 从状态字段中提取写锁计数
         * 通过掩码获取低16位
         * @param c 状态值
         * @return 写锁计数
         */
        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }

        /**
         * 线程本地变量,用于存储每个线程的读锁重入计数
         * 
         * 设计目的:
         * - 跟踪每个线程持有的读锁数量
         * - 支持读锁的可重入性
         * - 避免竞争和同步开销
         * 
         * 数据结构:
         * - 使用ThreadLocal实现线程隔离
         * - 每个线程维护自己的计数器
         */
        static final class HoldCounter {
            int count = 0;          // 读锁计数
            final long tid = getThreadId(Thread.currentThread()); // 线程ID

            /**
             * 递增计数
             * @return 递增后的值
             */
            final int tryInc() {
                int c = count;
                if (c < 0) // 检查溢出
                    throw new Error("Maximum lock count exceeded");
                return count = c + 1;
            }
        }

        /**
         * 线程本地持有计数器
         * 继承自ThreadLocal,提供线程本地存储
         */
        static final class ThreadLocalHoldCounter
            extends ThreadLocal<HoldCounter> {
            /**
             * 初始化方法
             * 为每个线程创建新的HoldCounter
             * @return 新的HoldCounter实例
             */
            public HoldCounter initialValue() {
                return new HoldCounter();
            }
        }

        /**
         * 线程本地持有计数器实例
         * 用于跟踪每个线程的读锁持有情况
         */
        private transient ThreadLocalHoldCounter readHolds;

        /**
         * 第一个读线程的持有计数器缓存
         * 优化:避免频繁的ThreadLocal访问
         */
        private transient HoldCounter cachedHoldCounter;

        /**
     * 第一个获取读锁的线程
         * 用于优化单个读线程的场景
         */
        private transient Thread firstReader = null;

        /**
         * 第一个读线程的持有计数
         * 与firstReader配合使用
         */
        private transient int firstReaderHoldCount;

        /**
         * 构造方法
         * 初始化ThreadLocal持有计数器
         */
        Sync() {
            readHolds = new ThreadLocalHoldCounter();
            setState(getState()); // ensures visibility of readHolds
        }

        /**
         * 获取线程ID的优化方法
         * 使用sun.misc.Unsafe直接获取线程ID
         * 避免Thread.getId()的同步开销
         * @param thread 线程
         * @return 线程ID
         */
        static final long getThreadId(Thread thread) {
            return UNSAFE.getLongVolatile(thread, TID_OFFSET);
        }

        /**
         * 尝试获取写锁(非公平方式)
         * @param acquires 获取许可数
         * @return 如果获取成功返回true,否则返回false
         * 
         * 获取过程:
         * 1. 检查是否有读锁持有者
         * 2. 检查写锁是否可重入
         * 3. 如果可以获取,更新状态并设置独占线程
         */
        final boolean tryWriteLock() {
            Thread current = Thread.currentThread();
            int c = getState();
            if (c != 0) {
                int w = exclusiveCount(c);
                if (w == 0 || current != getExclusiveOwnerThread())
                    return false;
                if (w == MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
            }
            if (!compareAndSetState(c, c + 1))
                return false;
            setExclusiveOwnerThread(current);
            return true;
        }

        /**
         * 尝试获取读锁(非公平方式)
         * @param acquires 获取许可数
         * @return 如果获取成功返回true,否则返回false
         * 
         * 获取过程:
         * 1. 检查是否有写锁持有者(且不是当前线程)
         * 2. 增加读锁计数
         * 3. 更新线程本地计数器
         */
        final boolean tryReadLock() {
            Thread current = Thread.currentThread();
            for (;;) {
                int c = getState();
                if (exclusiveCount(c) != 0 &&
                    getExclusiveOwnerThread() != current)
                    return false;
                int r = sharedCount(c);
                if (r == MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                if (compareAndSetState(c, c + SHARED_UNIT)) {
                    if (r == 0) {
                        firstReader = current;
                        firstReaderHoldCount = 1;
                    } else if (firstReader == current) {
                        firstReaderHoldCount++;
                    } else {
                        HoldCounter rh = cachedHoldCounter;
                        if (rh == null || rh.tid != getThreadId(current))
                            cachedHoldCounter = rh = readHolds.get();
                        else if (rh.count == 0)
                            readHolds.set(rh);
                        rh.count++;
                    }
                    return true;
                }
            }
        }

        /**
         * 判断当前线程是否是第一个读线程
         * @return 如果是返回true,否则返回false
         */
        final boolean isFirstReader() {
            return firstReader == Thread.currentThread();
        }

        /**
         * 获取第一个读线程的持有计数
         * @return 持有计数
         */
        final int getFirstReaderHoldCount() {
            return firstReader == Thread.currentThread() ? firstReaderHoldCount : 0;
        }

        /**
         * 获取指定线程的读锁持有计数
         * @param t 线程
         * @return 持有计数
         */
        final int getReadHoldCount(Thread t) {
            if (t == null)
                throw new NullPointerException();
            if (isFirstReader())
                return firstReaderHoldCount;
            HoldCounter rh = cachedHoldCounter;
            if (rh != null && rh.tid == getThreadId(t))
                return rh.count;
            rh = readHolds.get();
            return rh == null ? 0 : rh.count;
        }

        /**
         * 检查是否应该阻塞写锁获取
         * 公平锁和非公平锁有不同的实现
         * @return 如果应该阻塞返回true,否则返回false
         */
        abstract boolean writerShouldBlock();

        /**
         * 检查是否应该阻塞读锁获取
         * 公平锁和非公平锁有不同的实现
         * @return 如果应该阻塞返回true,否则返回false
         */
        abstract boolean readerShouldBlock();

        /**
         * 尝试获取写锁
         * @param acquires 获取许可数
         * @return 如果获取成功返回true,否则返回false
         */
        protected final boolean tryAcquire(int acquires) {
            Thread current = Thread.currentThread();
            int c = getState();
            int w = exclusiveCount(c);
            if (c != 0) {
                // (Note: if c != 0 and w == 0 then shared count != 0)
                if (w == 0 || current != getExclusiveOwnerThread())
                    return false;
                if (w + exclusiveCount(acquires) > MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                // Reentrant acquire
                setState(c + acquires);
                return true;
            }
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires))
                return false;
            setExclusiveOwnerThread(current);
            return true;
        }

        /**
         * 尝试释放写锁
         * @param releases 释放许可数
         * @return 如果完全释放返回true,否则返回false
         */
        protected final boolean tryRelease(int releases) {
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            int nextc = getState() - releases;
            boolean free = exclusiveCount(nextc) == 0;
            if (free)
                setExclusiveOwnerThread(null);
            setState(nextc);
            return free;
        }

        /**
         * 尝试获取读锁
         * @param unused 未使用参数
         * @return 如果获取成功返回true,否则返回false
         */
        protected final boolean tryAcquireShared(int unused) {
            Thread current = Thread.currentThread();
            int c = getState();
            if (exclusiveCount(c) != 0 &&
                getExclusiveOwnerThread() != current)
                return -1;
            int r = sharedCount(c);
            if (!readerShouldBlock() &&
                r < MAX_COUNT &&
                compareAndSetState(c, c + SHARED_UNIT)) {
                if (r == 0) {
                    firstReader = current;
                    firstReaderHoldCount = 1;
                } else if (firstReader == current) {
                    firstReaderHoldCount++;
                } else {
                    HoldCounter rh = cachedHoldCounter;
                    if (rh == null || rh.tid != getThreadId(current))
                        cachedHoldCounter = rh = readHolds.get();
                    else if (rh.count == 0)
                        readHolds.set(rh);
                    rh.count++;
                }
                return 1;
            }
            return fullTryAcquireShared(current);
        }

        /**
         * 完整的读锁获取尝试
         * 处理CAS失败和阻塞检查的情况
         * @param current 当前线程
         * @return 获取结果
         */
        final int fullTryAcquireShared(Thread current) {
            HoldCounter rh = null;
            for (;;) {
                int c = getState();
                if (exclusiveCount(c) != 0) {
                    if (getExclusiveOwnerThread() != current)
                        return -1;
                } else if (readerShouldBlock()) {
                    // Make sure we're not acquiring read lock reentrantly
                    if (firstReader == current) {
                        // assert firstReaderHoldCount > 0;
                    } else {
                        if (rh == null) {
                            rh = cachedHoldCounter;
                            if (rh == null || rh.tid != getThreadId(current)) {
                                rh = readHolds.get();
                                if (rh.count == 0)
                                    readHolds.remove();
                            }
                        }
                        if (rh.count == 0)
                            return -1;
                    }
                }
                if (sharedCount(c) == MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                if (compareAndSetState(c, c + SHARED_UNIT)) {
                    if (sharedCount(c) == 0) {
                        firstReader = current;
                        firstReaderHoldCount = 1;
                    } else if (firstReader == current) {
                        firstReaderHoldCount++;
                    } else {
                        if (rh == null)
                            rh = cachedHoldCounter;
                        if (rh == null || rh.tid != getThreadId(current))
                            rh = readHolds.get();
                        else if (rh.count == 0)
                            readHolds.set(rh);
                        rh.count++;
                        cachedHoldCounter = rh; // cache for release
                    }
                    return 1;
                }
            }
        }

        /**
         * 尝试释放读锁
         * @param unused 未使用参数
         * @return 如果完全释放返回true,否则返回false
         */
        protected final boolean tryReleaseShared(int unused) {
            Thread current = Thread.currentThread();
            if (firstReader == current) {
                // assert firstReaderHoldCount > 0;
                if (firstReaderHoldCount == 1)
                    firstReader = null;
                else
                    firstReaderHoldCount--;
            } else {
                HoldCounter rh = cachedHoldCounter;
                if (rh == null || rh.tid != getThreadId(current))
                    rh = readHolds.get();
                int count = rh.count;
                if (count <= 1) {
                    readHolds.remove();
                    if (count <= 0)
                        throw unmatchedUnlockException();
                }
                --rh.count;
            }
            for (;;) {
                int c = getState();
                int nextc = c - SHARED_UNIT;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }

        /**
         * 创建未匹配解锁异常
         * @return IllegalMonitorStateException实例
         */
        private IllegalMonitorStateException unmatchedUnlockException() {
            return new IllegalMonitorStateException(
                "attempt to unlock read lock, not locked by current thread");
        }

        /**
         * 获取写锁持有线程
         * @return 持有写锁的线程,如果未被持有则返回null
         */
        protected final Thread getOwner() {
            // Must read state before owner to ensure memory consistency
            return ((exclusiveCount(getState()) == 0) ?
                    null :
                    getExclusiveOwnerThread());
        }

        /**
         * 获取读锁持有计数
         * @return 读锁持有计数
         */
        protected final int getReadLockCount() {
            return sharedCount(getState());
        }

        /**
         * 判断是否持有写锁
         * @return 如果持有写锁返回true,否则返回false
         */
        protected final boolean isWriteLocked() {
            return exclusiveCount(getState()) != 0;
        }

        /**
         * 判断当前线程是否持有写锁
         * @return 如果当前线程持有写锁返回true,否则返回false
         */
        protected final boolean isWriteLockedByCurrentThread() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }

        /**
         * 获取写锁重入计数
         * @return 重入计数
         */
        protected final int getWriteHoldCount() {
            return isWriteLockedByCurrentThread() ? exclusiveCount(getState()) : 0;
        }

        // Unsafe相关字段和方法
        private static final sun.misc.Unsafe UNSAFE;
        private static final long TID_OFFSET;

        static {
            try {
                UNSAFE = sun.misc.Unsafe.getUnsafe();
                Class<?> tk = Thread.class;
                TID_OFFSET = UNSAFE.objectFieldOffset
                    (tk.getDeclaredField("tid"));
            } catch (Exception e) {
                throw new Error(e);
            }
        }
    }

    /**
     * 非公平同步器实现
     */
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = -8159625535654395037L;

        /**
         * 写锁不应该阻塞(非公平)
         * 允许写锁插队
         * @return 总是返回false
         */
        final boolean writerShouldBlock() {
            return false; // writers can always barge
        }

        /**
         * 读锁不应该阻塞(非公平)
         * 允许读锁插队
         * @return 总是返回false
         */
        final boolean readerShouldBlock() {
            return apparentlyFirstQueuedIsExclusive();
        }
    }

    /**
     * 公平同步器实现
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -2274990926593161451L;

        /**
         * 写锁应该阻塞(公平)
         * 检查等待队列中是否有前驱节点
         * @return 如果应该阻塞返回true,否则返回false
         */
        final boolean writerShouldBlock() {
            return hasQueuedPredecessors();
        }

        /**
         * 读锁应该阻塞(公平)
         * 检查等待队列中是否有前驱节点
         * @return 如果应该阻塞返回true,否则返回false
         */
        final boolean readerShouldBlock() {
            return hasQueuedPredecessors();
        }
    }

2. 读锁实现(详细注释)

    /**
     * 读锁实现类
     * 提供共享锁语义
     */
    public static class ReadLock implements Lock, java.io.Serializable {
        private static final long serialVersionUID = -5992448646407690164L;

        /**
         * 关联的ReentrantReadWriteLock实例
         */
        private final Sync sync;

        /**
         * 构造方法
         * @param lock 关联的ReentrantReadWriteLock
         */
        protected ReadLock(ReentrantReadWriteLock lock) {
            sync = lock.sync;
        }

        /**
         * 获取读锁
         * 如果写锁被其他线程持有,当前线程会阻塞
         * 
         * 获取过程:
         * 1. 尝试直接获取读锁
         * 2. 如果获取失败,加入等待队列
         * 3. 阻塞当前线程直到被唤醒
         * 4. 被唤醒后重新尝试获取读锁
         * 
         * 可重入性:
         * - 同一线程可以多次获取读锁
         * - 每次获取都会增加读锁计数
         * - 每次释放都会减少读锁计数
         * - 只有当所有读锁都释放后,写锁才能获取
         */
        public void lock() {
            sync.acquireShared(1); // 调用AQS的共享锁获取方法
        }

        /**
         * 获取读锁(可中断)
         * 与lock()不同的是,此方法响应中断
         * 
         * 中断处理:
         * - 如果线程在等待过程中被中断,会抛出InterruptedException
         * - 线程可以被优雅地中止
         * 
         * @throws InterruptedException 如果线程被中断
         */
        public void lockInterruptibly() throws InterruptedException {
            sync.acquireSharedInterruptibly(1); // 调用AQS的可中断共享锁获取方法
        }

        /**
         * 尝试获取读锁(非阻塞)
         * 立即返回,不会阻塞当前线程
         * 
         * 获取结果:
         * - 如果读锁可用,立即获取并返回true
         * - 如果读锁不可用,立即返回false
         * 
         * 使用场景:
         * - 避免线程阻塞
         * - 实现超时控制
         * - 检查锁的状态
         * 
         * @return 如果获取成功返回true,否则返回false
         */
        public boolean tryLock() {
            return sync.tryReadLock(); // 调用sync的tryReadLock方法
        }

        /**
         * 尝试获取读锁(带超时)
         * 如果读锁不可用,等待指定时间
         * 
         * 超时处理:
         * - 在指定时间内获取锁,返回true
         * - 超时未获取到锁,返回false
         * - 等待过程中可被中断
         * 
         * @param timeout 等待时间
         * @param unit 时间单位
         * @return 如果获取成功返回true,否则返回false
         * @throws InterruptedException 如果线程被中断
         */
        public boolean tryLock(long timeout, TimeUnit unit)
                throws InterruptedException {
            return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
        }

        /**
         * 释放读锁
         * 减少读锁计数,如果为0则完全释放读锁
         * 
         * 释放过程:
         * 1. 减少读锁计数
         * 2. 如果计数为0,唤醒等待的写锁线程
         * 3. 允许写锁获取
         * 
         * 异常处理:
         * - 如果当前线程没有持有读锁,抛出IllegalMonitorStateException
         */
        public void unlock() {
            sync.releaseShared(1); // 调用AQS的共享锁释放方法
        }

        /**
         * 读锁不支持Condition
         * @throws UnsupportedOperationException 总是抛出此异常
         */
        public Condition newCondition() {
            throw new UnsupportedOperationException();
        }

        /**
         * 返回读锁的字符串表示
         * @return 字符串表示
         */
        public String toString() {
            int r = sync.getReadLockCount();
            return super.toString() +
                "[Read locks = " + r + "]";
        }
    }

3. 写锁实现(详细注释)

    /**
     * 写锁实现类
     * 提供独占锁语义
     */
    public static class WriteLock implements Lock, java.io.Serializable {
        private static final long serialVersionUID = -4992448646407690164L;

        /**
         * 关联的ReentrantReadWriteLock实例
         */
        private final Sync sync;

        /**
         * 构造方法
         * @param lock 关联的ReentrantReadWriteLock
         */
        protected WriteLock(ReentrantReadWriteLock lock) {
            sync = lock.sync;
        }

        /**
         * 获取写锁
         * 如果读锁或写锁被其他线程持有,当前线程会阻塞
         * 
         * 获取过程:
         * 1. 尝试直接获取写锁
         * 2. 如果获取失败,加入等待队列
         * 3. 阻塞当前线程直到被唤醒
         * 4. 被唤醒后重新尝试获取写锁
         * 
         * 可重入性:
         * - 同一线程可以多次获取写锁
         * - 每次获取都会增加写锁计数
         * - 每次释放都会减少写锁计数
         * - 只有当写锁计数为0时,其他线程才能获取读锁或写锁
         */
        public void lock() {
            sync.acquire(1); // 调用AQS的独占锁获取方法
        }

        /**
         * 获取写锁(可中断)
         * 与lock()不同的是,此方法响应中断
         * 
         * 中断处理:
         * - 如果线程在等待过程中被中断,会抛出InterruptedException
         * - 线程可以被优雅地中止
         * 
         * @throws InterruptedException 如果线程被中断
         */
        public void lockInterruptibly() throws InterruptedException {
            sync.acquireInterruptibly(1); // 调用AQS的可中断独占锁获取方法
        }

        /**
         * 尝试获取写锁(非阻塞)
         * 立即返回,不会阻塞当前线程
         * 
         * 获取结果:
         * - 如果写锁可用,立即获取并返回true
         * - 如果写锁不可用,立即返回false
         * 
         * 使用场景:
         * - 避免线程阻塞
         * - 实现超时控制
         * - 检查锁的状态
         * 
         * @return 如果获取成功返回true,否则返回false
         */
        public boolean tryLock() {
            return sync.tryWriteLock(); // 调用sync的tryWriteLock方法
        }

        /**
         * 尝试获取写锁(带超时)
         * 如果写锁不可用,等待指定时间
         * 
         * 超时处理:
         * - 在指定时间内获取锁,返回true
         * - 超时未获取到锁,返回false
         * - 等待过程中可被中断
         * 
         * @param timeout 等待时间
         * @param unit 时间单位
         * @return 如果获取成功返回true,否则返回false
         * @throws InterruptedException 如果线程被中断
         */
        public boolean tryLock(long timeout, TimeUnit unit)
                throws InterruptedException {
            return sync.tryAcquireNanos(1, unit.toNanos(timeout));
        }

        /**
         * 释放写锁
         * 减少写锁计数,如果为0则完全释放写锁
         * 
         * 释放过程:
         * 1. 减少写锁计数
         * 2. 如果计数为0,完全释放写锁
         * 3. 唤醒等待队列中的线程
         * 4. 允许其他线程获取读锁或写锁
         * 
         * 异常处理:
         * - 如果当前线程不是写锁的持有者,抛出IllegalMonitorStateException
         */
        public void unlock() {
            sync.release(1); // 调用AQS的独占锁释放方法
        }

        /**
         * 创建新的Condition实例
         * 写锁支持Condition,与ReentrantLock类似
         * 
         * Condition特点:
         * - 与特定的写锁实例绑定
         * - 支持线程等待/通知机制
         * - 更灵活的控制
         * 
         * @return 新的Condition实例
         */
        public Condition newCondition() {
            return sync.newCondition();
        }

        /**
         * 返回写锁的字符串表示
         * @return 字符串表示
         */
        public String toString() {
            Thread o = sync.getOwner();
            return super.toString() +
                ((o == null) ?
                 "[Unlocked]" :
                 "[Locked by thread " + o.getName() + "]");
        }
    }

4. 查询和状态方法(详细注释)

    /**
     * 判断是否持有写锁
     * @return 如果持有写锁返回true,否则返回false
     * 
     * 查询结果:
     * - 如果任何线程持有写锁返回true
     * - 如果没有线程持有写锁返回false
     * 
     * 使用场景:
     * - 监控锁的状态
     * - 实现复杂的同步逻辑
     * - 调试和诊断
     */
    public boolean isWriteLocked() {
        return sync.isWriteLocked();
    }

    /**
     * 判断当前线程是否持有写锁
     * @return 如果当前线程持有写锁返回true,否则返回false
     * 
     * 查询结果:
     * - 如果当前线程持有写锁返回true
     * - 否则返回false
     * 
     * 使用场景:
     * - 检查锁的持有情况
     * - 实现可重入逻辑
     * - 避免重复获取锁
     */
    public boolean isWriteLockedByCurrentThread() {
        return sync.isWriteLockedByCurrentThread();
    }

    /**
     * 获取写锁重入计数
     * @return 重入计数
     * 
     * 查询结果:
     * - 如果当前线程持有写锁,返回重入次数
     * - 如果当前线程未持有写锁,返回0
     * 
     * 使用场景:
     * - 调试和监控
     * - 实现复杂的同步逻辑
     * - 避免过度释放锁
     */
    public int getWriteHoldCount() {
        return sync.getWriteHoldCount();
    }

    /**
     * 获取读锁持有计数
     * @return 读锁持有计数
     * 
     * 查询结果:
     * - 返回当前持有的读锁总数
     * - 包括所有线程持有的读锁
     * 
     * 使用场景:
     * - 监控读锁的使用情况
     * - 实现负载监控
     * - 性能调优
     */
    public int getReadLockCount() {
        return sync.getReadLockCount();
    }

    /**
     * 获取指定线程的读锁持有计数
     * @param thread 要查询的线程
     * @return 读锁持有计数
     * 
     * 查询结果:
     * - 返回指定线程持有的读锁数量
     * - 如果线程未持有读锁返回0
     * 
     * 使用场景:
     * - 调试和诊断
     * - 实现复杂的同步逻辑
     * - 分析线程状态
     */
    public int getReadHoldCount(Thread thread) {
        return sync.getReadHoldCount(thread);
    }

    /**
     * 获取当前线程的读锁持有计数
     * @return 读锁持有计数
     * 
     * 查询结果:
     * - 返回当前线程持有的读锁数量
     * - 如果未持有读锁返回0
     * 
     * 使用场景:
     * - 检查锁的持有情况
     * - 实现可重入逻辑
     * - 避免重复获取锁
     */
    public int getReadHoldCount() {
        return sync.getReadHoldCount(Thread.currentThread());
    }

    /**
     * 判断锁是否是公平锁
     * @return 如果是公平锁返回true,否则返回false
     * 
     * 查询结果:
     * - 通过检查sync的类型来判断
     * - FairSync类型表示公平锁
     * - NonfairSync类型表示非公平锁
     */
    public final boolean isFair() {
        return sync instanceof FairSync;
    }

    /**
     * 获取当前持有写锁的线程
     * @return 持有写锁的线程,如果未被持有则返回null
     * 
     * 查询结果:
     * - 如果写锁被持有,返回持有线程
     * - 如果写锁空闲,返回null
     * 
     * 使用场景:
     * - 调试和监控
     * - 实现诊断工具
     * - 分析死锁情况
     */
    protected Thread getOwner() {
        return sync.getOwner();
    }

    /**
     * 查询是否有线程正在等待获取写锁
     * @return 如果有等待线程返回true,否则返回false
     * 
     * 查询结果:
     * - 检查AQS的同步队列
     * - 如果有等待写锁的线程返回true
     * - 否则返回false
     * 
     * 使用场景:
     * - 监控锁的竞争情况
     * - 实现负载均衡
     * - 优化系统性能
     */
    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    /**
     * 查询指定线程是否正在等待获取锁
     * @param thread 要查询的线程
     * @return 如果线程在等待队列中返回true,否则返回false
     * 
     * 查询结果:
     * - 如果指定线程在等待队列中返回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. ReentrantReadWriteLock 的特点分析

核心设计理念:

/**
 * ReentrantReadWriteLock的核心设计思想:
 * 
 * 1. 读写分离:
 *    - 读锁:共享锁,多个读线程可以同时持有
 *    - 写锁:独占锁,写线程独占访问
 *    - 读读不互斥,读写互斥,写写互斥
 * 
 * 2. 状态管理:
 *    - 使用一个int字段管理两种锁的状态
 *    - 高16位表示读锁计数
 *    - 低16位表示写锁计数
 *    - 通过位运算高效管理状态
 * 
 * 3. 可重入性:
 *    - 支持读锁和写锁的可重入
 *    - 每个线程维护自己的持有计数
 *    - 完全释放时才允许其他线程获取
 * 
 * 4. 公平性选择:
 *    - 提供公平和非公平两种模式
 *    - 公平锁避免线程饥饿
 *    - 非公平锁提高性能
 * 
 * 5. 线程本地存储:
 *    - 使用ThreadLocal跟踪每个线程的读锁持有情况
 *    - 避免竞争和同步开销
 *    - 优化单个读线程的场景
 * 
 * 6. AQS集成:
 *    - 继承AbstractQueuedSynchronizer
 *    - 复用成熟的队列管理机制
 *    - 提供完整的同步框架
 * 
 * 适用场景:
 * - 读操作远多于写操作的场景
 * - 需要高并发读取的场景
 * - 需要比ReentrantLock更细粒度控制的场景
 * - 需要Condition支持的写锁场景
 */

性能特征分析:

/**
 * ReentrantReadWriteLock的性能特征:
 * 
 * 获取锁时间复杂度:
 * - 无竞争读锁:O(1) - 直接CAS操作
 * - 无竞争写锁:O(1) - 直接CAS操作
 * - 有竞争:O(1) 平均,O(n) 最坏(等待队列长度)
 * 
 * 释放锁时间复杂度:
 * - 读锁释放:O(1) - 更新状态并可能唤醒写锁
 * - 写锁释放:O(1) - 更新状态并唤醒等待线程
 * 
 * 内存复杂度:
 * - O(1) 基本开销
 * - O(n) 等待队列开销(n为等待线程数)
 * - O(t) ThreadLocal开销(t为持有读锁的线程数)
 * 
 * 并发特性:
 * - 完全线程安全
 * - 支持高并发读取
 * - 读写互斥保证数据一致性
 * - 无锁设计(通过CAS和AQS)
 * 
 * 读写性能对比:
 * - 读锁:多个线程可以并发获取
 * - 写锁:独占访问,性能相对较低
 * - 读多写少:性能优势明显
 * - 写多读少:可能不如ReentrantLock
 * 
 * 公平性对比:
 * - 非公平锁:吞吐量更高,可能有线程饥饿
 * - 公平锁:避免饥饿,吞吐量略低
 * 
 * 与ReentrantLock对比:
 * - 读写分离:更细粒度的控制
 * - 读并发:支持多个读线程同时访问
 * - 复杂度:实现更复杂,开销略大
 * - 适用场景:读多写少的场景
 */

6. 使用示例和最佳实践

/**
 * 使用示例:
 * 
 * // 基本使用
 * ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 * Lock readLock = rwLock.readLock();
 * Lock writeLock = rwLock.writeLock();
 * 
 * // 读操作
 * readLock.lock();
 * try {
 *     // 读取共享数据
 *     // 多个读线程可以同时执行
 * } finally {
 *     readLock.unlock();
 * }
 * 
 * // 写操作
 * writeLock.lock();
 * try {
 *     // 修改共享数据
 *     // 独占访问,其他读写操作都会阻塞
 * } finally {
 *     writeLock.unlock();
 * }
 * 
 * // 可中断的锁获取
 * try {
 *     readLock.lockInterruptibly();
 *     try {
 *         // 读操作
 *     } finally {
 *         readLock.unlock();
 *     }
 * } catch (InterruptedException e) {
 *     Thread.currentThread().interrupt();
 * }
 * 
 * // 带超时的锁获取
 * try {
 *     if (writeLock.tryLock(5, TimeUnit.SECONDS)) {
 *         try {
 *             // 写操作
 *         } finally {
 *             writeLock.unlock();
 *         }
 *     } else {
 *         // 获取锁超时
 *         System.out.println("Failed to acquire write lock within timeout");
 *     }
 * } catch (InterruptedException e) {
 *     Thread.currentThread().interrupt();
 * }
 * 
 * // 公平锁
 * ReentrantReadWriteLock fairRwLock = new ReentrantReadWriteLock(true);
 * 
 * // 使用Condition(仅写锁支持)
 * Condition condition = writeLock.newCondition();
 * 
 * // 等待条件
 * writeLock.lock();
 * try {
 *     while (!conditionMet()) {
 *         condition.await();
 *     }
 *     // 条件满足后的处理
 * } finally {
 *     writeLock.unlock();
 * }
 * 
 * // 通知等待的线程
 * writeLock.lock();
 * try {
 *     // 改变条件
 *     setConditionMet(true);
 *     condition.signal(); // 或者 condition.signalAll();
 * } finally {
 *     writeLock.unlock();
 * }
 * 
 * 最佳实践:
 * 
 * 1. 正确的锁获取和释放:
 *    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 *    Lock readLock = rwLock.readLock();
 *    Lock writeLock = rwLock.writeLock();
 *    
 *    // 读操作
 *    readLock.lock();
 *    try {
 *        // 读取操作
 *    } finally {
 *        readLock.unlock(); // 必须在finally块中释放
 *    }
 *    
 *    // 写操作
 *    writeLock.lock();
 *    try {
 *        // 写入操作
 *    } finally {
 *        writeLock.unlock(); // 必须在finally块中释放
 *    }
 * 
 * 2. 避免读写锁嵌套:
 *    // 错误的做法:可能导致死锁
 *    readLock.lock();
 *    try {
 *        // 一些操作
 *        if (needToUpdate()) {
 *            writeLock.lock(); // 危险!可能导致死锁
 *            try {
 *                // 更新操作
 *            } finally {
 *                writeLock.unlock();
 *            }
 *        }
 *    } finally {
 *        readLock.unlock();
 *    }
 *    
 *    // 正确的做法:统一使用写锁
 *    writeLock.lock();
 *    try {
 *        // 读取操作
 *        // 更新操作
 *    } finally {
 *        writeLock.unlock();
 *    }
 * 
 * 3. 合理使用可重入性:
 *    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 *    private final Lock readLock = rwLock.readLock();
 *    private final Lock writeLock = rwLock.writeLock();
 *    
 *    public void outerReadMethod() {
 *        readLock.lock();
 *        try {
 *            innerReadMethod(); // 同一线程可以再次获取读锁
 *        } finally {
 *            readLock.unlock(); // 只需要一次unlock
 *        }
 *    }
 *    
 *    public void innerReadMethod() {
 *        readLock.lock();
 *        try {
 *            // 读取操作
 *            System.out.println("Read hold count: " + rwLock.getReadHoldCount());
 *        } finally {
 *            readLock.unlock();
 *        }
 *    }
 * 
 * 4. 选择合适的公平性:
 *    // 读多写少且对公平性要求不高:非公平锁(默认)
 *    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 *    
 *    // 需要避免饥饿:公平锁
 *    ReentrantReadWriteLock fairRwLock = new ReentrantReadWriteLock(true);
 * 
 * 5. 设置合理的超时时间:
 *    try {
 *        if (readLock.tryLock(10, TimeUnit.SECONDS)) {
 *            try {
 *                // 读操作
 *            } finally {
 *                readLock.unlock();
 *            }
 *        } else {
 *            // 超时处理
 *            System.out.println("Read operation timed out");
 *        }
 *    } catch (InterruptedException e) {
 *        Thread.currentThread().interrupt();
 *    }
 * 
 * 6. 监控锁的使用情况:
 *    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 *    
 *    // 检查锁的状态
 *    if (rwLock.isWriteLocked()) {
 *        System.out.println("Write lock is currently held");
 *    }
 *    
 *    if (rwLock.isWriteLockedByCurrentThread()) {
 *        System.out.println("Current thread holds the write lock");
 *        System.out.println("Write hold count: " + rwLock.getWriteHoldCount());
 *    }
 *    
 *    System.out.println("Read lock count: " + rwLock.getReadLockCount());
 *    System.out.println("Current thread read hold count: " + rwLock.getReadHoldCount());
 *    
 *    // 检查等待队列
 *    if (rwLock.hasQueuedThreads()) {
 *        System.out.println("Threads waiting for lock: " + rwLock.getQueueLength());
 *    }
 * 
 * 7. 使用Condition(仅写锁支持):
 *    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 *    private final Lock writeLock = rwLock.writeLock();
 *    private final Condition notFull = writeLock.newCondition();
 *    private final Condition notEmpty = writeLock.newCondition();
 *    
 *    // 生产者
 *    public void put(Object item) throws InterruptedException {
 *        writeLock.lock();
 *        try {
 *            while (isFull()) {
 *                notFull.await(); // 等待空间
 *            }
 *            // 添加元素
 *            notEmpty.signal(); // 通知消费者
 *        } finally {
 *            writeLock.unlock();
 *        }
 *    }
 *    
 *    // 消费者
 *    public Object take() throws InterruptedException {
 *        writeLock.lock();
 *        try {
 *            while (isEmpty()) {
 *                notEmpty.await(); // 等待元素
 *            }
 *            Object item = remove(); // 移除元素
 *            notFull.signal(); // 通知生产者
 *            return item;
 *        } finally {
 *            writeLock.unlock();
 *        }
 *    }
 * 
 * 8. 避免长时间持有锁:
 *    // 错误的做法:长时间持有锁
 *    writeLock.lock();
 *    try {
 *        // 大量计算或I/O操作
 *        expensiveOperation(); // 不应该在锁内执行
 *        // 更新共享数据
 *    } finally {
 *        writeLock.unlock();
 *    }
 *    
 *    // 正确的做法:减少锁持有时间
 *    Object result = expensiveOperation(); // 在锁外执行
 *    writeLock.lock();
 *    try {
 *        // 只在必要时持有锁
 *        updateSharedData(result);
 *    } finally {
 *        writeLock.unlock();
 *    }
 * 
 * 9. 处理异常:
 *    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 *    Lock readLock = rwLock.readLock();
 *    
 *    readLock.lock();
 *    try {
 *        // 可能抛出异常的代码
 *        riskyReadOperation();
 *    } catch (Exception e) {
 *        // 处理异常
 *        System.err.println("Read operation failed: " + e.getMessage());
 *        throw e; // 重新抛出或处理
 *    } finally {
 *        readLock.unlock(); // 确保锁被释放
 *    }
 * 
 * 10. 性能调优:
 *    // 在高并发读场景下监控性能
 *    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
 *    
 *    // 定期检查锁的使用情况
 *    if (rwLock.getReadLockCount() > 1000) {
 *        System.out.println("High read contention detected");
 *        // 可能需要优化数据结构或访问模式
 *    }
 *    
 *    if (rwLock.getQueueLength() > 100) {
 *        System.out.println("High lock contention detected");
 *        // 可能需要减少锁的粒度
 *    }
 */

7. 与其他同步机制的比较

/**
 * ReentrantReadWriteLock vs ReentrantLock vs synchronized vs StampedLock:
 * 
 * ReentrantReadWriteLock:
 * - 读写分离,读读不互斥
 * - 支持多个读线程并发访问
 * - 写锁独占访问
 * - 支持公平性和非公平性
 * - 读锁不支持Condition
 * - 写锁支持Condition
 * 
 * ReentrantLock:
 * - 独占锁,读写都互斥
 * - 不区分读写操作
 * - 支持公平性和非公平性
 * - 支持Condition
 * - 实现相对简单
 * 
 * synchronized:
 * - JVM内置锁
 * - 自动释放锁
 * - JVM优化(偏向锁、轻量级锁等)
 * - 不支持读写分离
 * - 不支持公平性选择
 * - 不支持Condition(Object的wait/notify)
 * 
 * StampedLock:
 * - JDK 8新增
 * - 更高性能的读写锁
 * - 支持乐观读
 * - 不支持重入
 * - 不支持Condition
 * - 更复杂的使用方式
 * 
 * 选择建议:
 * - 读多写少:ReentrantReadWriteLock
 * - 简单同步需求:synchronized
 * - 需要Condition:ReentrantLock
 * - 高性能读操作:StampedLock
 * - 复杂同步逻辑:ReentrantLock
 * 
 * 性能对比:
 * - 无竞争:synchronized ≈ ReentrantLock ≈ ReentrantReadWriteLock
 * - 有竞争:ReentrantLock ≥ synchronized(JDK 1.6后)
 * - 读多写少:ReentrantReadWriteLock > ReentrantLock > synchronized
 * - 高并发读:StampedLock > ReentrantReadWriteLock
 * - 写多读少:ReentrantLock ≥ ReentrantReadWriteLock
 */

8. 总结

ReentrantReadWriteLock 的核心特性:

  1. 读写分离

    • 读锁:共享锁,多个读线程可以同时持有
    • 写锁:独占锁,写线程独占访问
    • 读读不互斥,读写互斥,写写互斥
  2. 可重入性

    • 支持读锁和写锁的可重入
    • 每个线程维护自己的持有计数
    • 完全释放时才允许其他线程获取
  3. 灵活性

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

    • 基于AQS实现,性能优秀
    • 无竞争时使用CAS操作
    • 有竞争时使用队列管理
    • 读并发提高整体性能
  5. 丰富的API

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

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

适用场景:

  • 读操作远多于写操作的场景
  • 需要高并发读取的场景
  • 需要比ReentrantLock更细粒度控制的场景
  • 需要Condition支持的写锁场景
  • 缓存系统、数据库访问等读多写少的应用

注意事项:

  • 必须在finally块中释放锁
  • 避免读写锁嵌套导致死锁
  • 合理选择公平性策略
  • 正确处理中断异常
  • 监控锁的使用情况
  • 避免长时间持有锁
  • 注意读写锁的语义区别

性能优化建议:

  1. 根据读写比例选择合适的锁类型
  2. 合理设置超时时间
  3. 使用公平锁避免线程饥饿
  4. 监控锁的竞争情况
  5. 优化临界区代码减少持有时间
  6. 考虑使用更细粒度的锁
  7. 定期分析和调优锁的使用
  8. 在读多写少的场景下充分发挥读并发优势
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值