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(); ... ... }