ReentrantReadWriteLock (读写锁)源码分析

关于AbstractQueuedSynchronizer中的独占锁,请参考ReentrantLock(http://www.cnblogs.com/bjorney/p/8040085.html)

1. ReentrantReadWriteLock

// ReentrantReadWriteLock本身不提供加锁服务,只负责提供读锁和写锁
public
class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { private final ReentrantReadWriteLock.ReadLock readerLock;
private final ReentrantReadWriteLock.WriteLock writerLock; final Sync sync; public ReentrantReadWriteLock() { this(false); } public ReentrantReadWriteLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new WriteLock(this); } public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } // 写锁 public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } // 读锁 // 总的读锁计数 public int getReadLockCount() { return sync.getReadLockCount(); } // 当前线程的写锁计数(当前线程必须占有锁) public int getWriteHoldCount() { return sync.getWriteHoldCount(); } // 当前线程的读锁计数 public int getReadHoldCount() { return sync.getReadHoldCount(); } // 获取所有在SyncQueue中排队的写线程 protected Collection<Thread> getQueuedWriterThreads() { return sync.getExclusiveQueuedThreads(); } // 获取所有在SyncQueue中排队的读线程 protected Collection<Thread> getQueuedReaderThreads() { return sync.getSharedQueuedThreads(); } ... ... static final long getThreadId(Thread thread) { return UNSAFE.getLongVolatile(thread, TID_OFFSET); // tid在Thread类中非volatile } 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); } } }

2. ReentrantReadWriteLock.ReadLock

public static class ReadLock implements Lock, java.io.Serializable {
    private final Sync sync;

    protected ReadLock(ReentrantReadWriteLock lock) {
        sync = lock.sync;
    }

    public void lock() { // 加读锁
        sync.acquireShared(1);
    }

    public void lockInterruptibly() throws InterruptedException { // 加读锁(可被中断)
        sync.acquireSharedInterruptibly(1);
    }

    public boolean tryLock() { // 尝试加读锁
        return sync.tryReadLock();
    }

    public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { // 加读锁(在timeOut内等锁)
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

    public void unlock() { // 释放读锁
        sync.releaseShared(1);
    }

    ... ...
}

3. ReentrantReadWriteLock.WriteLock

public static class WriteLock implements Lock, java.io.Serializable {
    private final Sync sync;

    protected WriteLock(ReentrantReadWriteLock lock) {
        sync = lock.sync;
    }

    public void lock() { // 加写锁
        sync.acquire(1);
    }

    public void lockInterruptibly() throws InterruptedException { // 加写锁(可被中断)
        sync.acquireInterruptibly(1);
    }

    public boolean tryLock( ) { // 尝试加写锁
        return sync.tryWriteLock();
    }

    public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { // 加写锁(在timeOut内等锁)
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

    public void unlock() { // 释放写锁
        sync.release(1);
    }

    ... ...
}

4. ReentrantReadWriteLock.Sync

abstract static class Sync extends AbstractQueuedSynchronizer {
    static final int SHARED_SHIFT   = 16; // state高16位为读锁计数,state低16位为写锁计数
    static final int SHARED_UNIT    = (1 << SHARED_SHIFT); // 读锁计数 + 1
    static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1; // 读(写)锁计数 <= 2^16 - 1
    static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; // 写锁计数 = state & (2^16 - 1)

    Sync() {
        readHolds = new ThreadLocalHoldCounter();
        setState(getState());
    }

    // return 锁状态(锁计数)
    final int getCount() { return getState(); }

    // 总的读锁计数
    final int getReadLockCount() {
        return sharedCount(getState());
    }
    static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }

    // 当前线程的写锁计数(当前线程必须占有锁)
    final int getWriteHoldCount() {
        return isHeldExclusively() ? exclusiveCount(getState()) : 0;
    }
    static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }

    // 当前线程的读锁计数
    final int getReadHoldCount() {
        if (getReadLockCount() == 0)
            return 0;

        Thread current = Thread.currentThread();
        if (firstReader == current)
            return firstReaderHoldCount;

        HoldCounter rh = cachedHoldCounter;
        if (rh != null && rh.tid == getThreadId(current))
            return rh.count;

        int count = readHolds.get().count;
        if (count == 0) readHolds.remove();
        return count;
    }

    private transient ThreadLocalHoldCounter readHolds; // 当前线程的读锁计数
    private transient HoldCounter cachedHoldCounter; // 缓存的线程读锁计数
    private transient Thread firstReader = null; // 首个读线程
    private transient int firstReaderHoldCount; // 首个读线程的读锁计数

    static final class HoldCounter {
        int count = 0;
        // tid在Thread类中非volatile
        // Thread.getId -> UNSAFE.getLongVolatile(Thread.currentThread(), Thread.class.getDeclaredField("tid"))
        final long tid = getThreadId(Thread.currentThread());
    }

    static final class ThreadLocalHoldCounter extends ThreadLocal<HoldCounter> {
        public HoldCounter initialValue() {
            return new HoldCounter(); // {0, currentThreadId}
        }
    }

    // 尝试取写锁
    protected final boolean tryAcquire(int acquires) {
        Thread current = Thread.currentThread();
        int c = getState();                         /*记录state*/
        int w = exclusiveCount(c); // 写锁计数w
        if (c != 0) {// 读线程未释放锁 || 当前线程不是锁的独占者
            if (w == 0 || current != getExclusiveOwnerThread())
                return false; // 取锁失败
            // 当前线程已占有锁(Reentrant)
            if (w + exclusiveCount(acquires) > MAX_COUNT)
                throw new Error("Maximum lock count exceeded");
            setState(c + acquires); // 更新锁状态,写锁计数++
            return true; // 成功取锁(已占有锁)
        }
        // state == 0
        if (writerShouldBlock() || // false(NonfairSync)|| hasQueuedPredecessors(FairSync)
            !compareAndSetState(c, c + acquires))   /*CAS设置state += acquires*/
            // CAS(state)失败
            return false; // 取锁失败
        // CAS(state)成功
        setExclusiveOwnerThread(current); // 设置当前线程为锁的独占者
        return true; // 成功取锁
    }

    // 尝试抢写锁,不进行writerShouldBlock判断
    final boolean tryWriteLock() {
        Thread current = Thread.currentThread();
        int c = getState();
        if (c != 0) {
            int w = exclusiveCount(c);  // 写锁计数w
            // 读线程未释放锁 || 当前线程不是锁的独占者
            if (w == 0 || current != getExclusiveOwnerThread())
                return false;
            // 当前线程已占有锁(Reentrant)
            if (w == MAX_COUNT)
                throw new Error("Maximum lock count exceeded");
        }
        if (!compareAndSetState(c, c + 1)) // CAS设置state += 1
            // CAS(state)失败
            return false; // 抢锁失败
        // CAS(state)成功
        setExclusiveOwnerThread(current);
        return true; // 抢锁成功
    }

    // 尝试取读锁
    protected final int tryAcquireShared(int unused) {
        Thread current = Thread.currentThread();
        int c = getState();                             /*记录state*/
        // 写线程未释放锁 && 未释放锁的写线程非当前线程(读写线程可为同一线程)
        if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) 
            return -1; // 取锁失败
        int r = sharedCount(c); // 读锁计数r
        if (!readerShouldBlock() && // apparentlyFirstQueuedIsExclusive(NonfairSync)|| hasQueuedPredecessors(FairSync)
            r < MAX_COUNT && // r未超过阈值
            compareAndSetState(c, c + SHARED_UNIT)) {   /*CAS设置state += SHARED_UNIT*/ // 读锁计数++
            // CAS(state)成功
            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) // 缓存的是当前线程的读锁计数,而当前线程的读锁计数在上次release时被删除
                    readHolds.set(rh);
                rh.count++;
            }
            return 1; // 成功取锁
        }
        // CAS(state)失败
        return fullTryAcquireShared(current);
    }

    // 不断尝试取读锁,直到取锁失败(写线程占有锁 || 当前线程的读锁计数为0) || 成功取锁
    final int fullTryAcquireShared(Thread current) {
        HoldCounter rh = null;
        for (;;) {
            // 当前线程的读锁计数不为0 && CAS(state)失败将回到此处
            int c = getState();                             /*记录state*/
            if (exclusiveCount(c) != 0) { // 写线程未释放锁
                if (getExclusiveOwnerThread() != current) // 当前线程不是锁的独占者
                    return -1;// 取锁失败
            } else if (readerShouldBlock()) {
                if (firstReader == current) {
                } else {
                    if (rh == null) {
                        rh = cachedHoldCounter;
                        if (rh == null || rh.tid != getThreadId(current)) {
                            rh = readHolds.get();
                            if (rh.count == 0) // 当前线程的读锁计数为0
                                readHolds.remove(); // 在线程局部变量中删除当前线程的读锁计数
                        }
                    }
                    if (rh.count == 0) // 当前线程的读锁计数为0
                        return -1; // 应排队取锁
                    // 继续尝试取锁
                }
            }
            if (sharedCount(c) == MAX_COUNT)
                throw new Error("Maximum lock count exceeded");
            if (compareAndSetState(c, c + SHARED_UNIT)) {   /*CAS设置state += SHARED_UNIT*/
                // CAS(state)成功
                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; // 成功取锁
            }
            // CAS(state)失败
        }
    }

    // 尝试抢读锁,不进行readerShouldBlock判断
    final boolean tryReadLock() {
        Thread current = Thread.currentThread();
        for (;;) {
            // CAS(state)失败将回到此处
            int c = getState();                             /*记录state*/
            // 写线程未释放锁 && 未释放锁的写线程非当前线程(读写线程可为同一线程)
            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)) {   /*CAS设置state += SHARED_UNIT*/
                // CAS(state)成功
                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; // 成功抢锁
            }
            // CAS(state)失败
        }
    }

    // 尝试释放写锁
    protected final boolean tryRelease(int releases) {
        if (!isHeldExclusively()) // 当前线程未占有锁
            throw new IllegalMonitorStateException();
        int nextc = getState() - releases;
        boolean free = exclusiveCount(nextc) == 0; // 写锁计数是否为0
        if (free) // 可释放锁
            setExclusiveOwnerThread(null); // 锁的独占者置空
        setState(nextc); // 更新锁状态
        return free;
    }

    // 尝试释放读锁
    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 (;;) {
            // CAS(state)失败将回到此处
            int c = getState();                 /*记录state*/
            int nextc = c - SHARED_UNIT; // 读锁计数--
            if (compareAndSetState(c, nextc))   /*CAS设置state = nextc*/
                // CAS(state)成功
                return nextc == 0;
            // CAS(state)失败
        }
    }

    ... ...
}

static final class NonfairSync extends Sync {
    final boolean writerShouldBlock() { // 写线程永远可以抢锁
        return false;
    }
    final boolean readerShouldBlock() { // SyncQueue排队的第一个节点(head.next)为写节点占锁时必须排队
        return apparentlyFirstQueuedIsExclusive();
    }
}

static final class FairSync extends Sync {
    final boolean writerShouldBlock() { // SyncQueue中下个待唤醒节点不是当前线程时必须排队
        return hasQueuedPredecessors();
    }
    final boolean readerShouldBlock() { // SyncQueue中下个待唤醒节点不是当前线程时必须排队
        return hasQueuedPredecessors();
    }
}

5. AbstractQueuedSynchronizer

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {

    // 尝试取读锁,取锁失败则排队等锁
    public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0) // 尝试取锁失败
            doAcquireShared(arg); // 排队等锁
    }

    // 排队等读锁
    private void doAcquireShared(int arg) {
        final Node node = addWaiter(Node.SHARED); // 在SyncQueue尾部添加读节点(共享锁:Node.SHARED)
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head) {
                    int r = tryAcquireShared(arg); // 尝试取读锁
                    if (r >= 0) { // tryAcquireShared成功
                        setHeadAndPropagate(node, r); // 置SyncQueue头结点为node,唤醒node后置位读节点
                        p.next = null; // help GC
                        if (interrupted)
                            selfInterrupt();
                        failed = false;
                        return;
                    }
                }
                if (shouldParkAfterFailedAcquire(p, node) && 
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    // 置SyncQueue头结点为node,唤醒node后置位读节点
    private void setHeadAndPropagate(Node node, int propagate) {
        Node h = head;
        setHead(node); // 置SyncQueue头结点为node
        if (propagate > 0 || h == null || h.waitStatus < 0 ||
            (h = head) == null || h.waitStatus < 0) {
            Node s = node.next; // s为node后置节点
            if (s == null || s.isShared()) // s为空 || s为读节点
                doReleaseShared(); // 唤醒s:s若取消排队(被中断 || 超时),则可能唤醒写节点
        }
    }

    // 尝试释放读锁,成功释放锁时unpark successor
    public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) { // 成功释放锁
            doReleaseShared(); // 唤醒后置位节点
            return true;
        }
        // 未释放锁
        return false;
    }

    // unpark successor
    private void doReleaseShared() {
        for (;;) {
            // CAS(head.waitStatus)失败将回到此处
            Node h = head;
            if (h != null && h != tail) {
                int ws = h.waitStatus;
                if (ws == Node.SIGNAL) { // head后置位节点等待被唤醒
                    // 可能其它读线程正在同步设置head.waitStatus
                    // A线程执行完毕后tryReleaseShared,锁被释放,B线程抢锁成功(未参与排队)
                    // B线程执行完毕后tryReleaseShared,A、B同步doReleaseShared
                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) // CAS设置head.waitStatus = 0
                        // CAS(head.waitStatus)失败
                        continue;
                    // CAS(head.waitStatus)成功
                    unparkSuccessor(h);
                    // 若此时是读线程在setHeadAndPropagate中释放后置位读节点,则可能唤醒写节点:
                    // 被唤醒的写节点若tryAcquire失败,则将在shouldParkAfterFailedAcquire中重置head.waitStatus = Node.SIGNAL
                }
                // ws == 0:head后置位节点为空 || head后置节点已被其它线程唤醒
                // 可能其它读线程正在同步设置head.waitStatus
                // A线程执行完毕后tryReleaseShared,锁被释放,B线程抢锁失败(未参与排队)
                // B线程在SyncQueue末尾添加新节点,并在shouldParkAfterFailedAcquire中同步设置head.waitStatus = Node.SIGNAL
                else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) // CAS设置head.waitStatus = Node.PROPAGATE
                    // CAS(head.waitStatus)失败
                    continue;
                // CAS(head.waitStatus)成功
            }
            if (h == head) // 后置位读节点被唤醒并成为head后,将继续唤醒后置读节点
                break;
        }
    }

    // 尝试取读锁,取锁失败则排队等锁(可被中断)
    public final void acquireSharedInterruptibly(int arg) throws InterruptedException;
    // 排队等读锁(可被中断)
    private void doAcquireSharedInterruptibly(int arg) throws InterruptedException;

    // 尝试取读锁,取锁失败则排队等锁(nanosTimeout时间内)
    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException;
    // 排队等读锁(nanosTimeout时间内)
    private boolean doAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException;

    // SyncQueue排队的第一个节点(head.next)为写节点
    final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null && // head不为空
            (s = h.next)  != null && // head存在后置节点
            !s.isShared()         && // head.next以独占方式取锁(为写节点)
            s.thread != null; // head.next未取消排队
    }

    // 获取所有在SyncQueue中排队的写线程
    public final Collection<Thread> getExclusiveQueuedThreads();

    // 获取所有在SyncQueue中排队的读线程
    public final Collection<Thread> getSharedQueuedThreads();

    ... ...
}
posted @ 2017-12-19 10:32  Uncle_Bjorney  阅读(691)  评论(0编辑  收藏  举报