voidprocessCachedData() { // 读锁 rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock // 释放读锁 rwl.readLock().unlock(); // 申请写锁 rwl.writeLock().lock(); try { // Recheck state because another thread might have // acquired write lock and changed state before we did. if (!cacheValid) { // 新数据的赋值 data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock // 降级成读锁 rwl.readLock().lock(); } finally { // 释放写锁,还持有读锁 rwl.writeLock().unlock(); // Unlock write, still hold read } }
/* * Read vs write count extraction constants and functions. * Lock state is logically divided into two unsigned shorts: * The lower one representing the exclusive (writer) lock hold count, * and the upper the shared (reader) hold count. */
/** * A counter for per-thread read hold counts. * Maintained as a ThreadLocal; cached in cachedHoldCounter. */ // 每个线程持有的读锁的数量 staticfinalclassHoldCounter { int count; // initially 0 // Use id, not reference, to avoid garbage retention finallongtid= LockSupport.getThreadId(Thread.currentThread()); }
/** * ThreadLocal subclass. Easiest to explicitly define for sake * of deserialization mechanics. */ // 用ThreadLocal记录每个线程持有的读锁的数量 staticfinalclassThreadLocalHoldCounter extendsThreadLocal<HoldCounter> { public HoldCounter initialValue() { returnnewHoldCounter(); } }
/** * The number of reentrant read locks held by current thread. * Initialized only in constructor and readObject. * Removed whenever a thread's read hold count drops to 0. */ // 当前线程的读锁持有数量 privatetransient ThreadLocalHoldCounter readHolds;
/** * The hold count of the last thread to successfully acquire * readLock. This saves ThreadLocal lookup in the common case * where the next thread to release is the last one to * acquire. This is non-volatile since it is just used * as a heuristic, and would be great for threads to cache. * * <p>Can outlive the Thread for which it is caching the read * hold count, but avoids garbage retention by not retaining a * reference to the Thread. * * <p>Accessed via a benign data race; relies on the memory * model's final field and out-of-thin-air guarantees. */ // 上一个成功获取读锁的线程持有的数量 privatetransient HoldCounter cachedHoldCounter;
/** * firstReader is the first thread to have acquired the read lock. * firstReaderHoldCount is firstReader's hold count. * * <p>More precisely, firstReader is the unique thread that last * changed the shared count from 0 to 1, and has not released the * read lock since then; null if there is no such thread. * * <p>Cannot cause garbage retention unless the thread terminated * without relinquishing its read locks, since tryReleaseShared * sets it to null. * * <p>Accessed via a benign data race; relies on the memory * model's out-of-thin-air guarantees for references. * * <p>This allows tracking of read holds for uncontended read * locks to be very cheap. */ // 第一个申请读锁的线程 // 第一个申请读锁的线程,现在持有的读锁数量. privatetransient Thread firstReader; privatetransientint firstReaderHoldCount;
/* * Note that tryRelease and tryAcquire can be called by * Conditions. So it is possible that their arguments contain * both read and write holds that are all released during a * condition wait and re-established in tryAcquire. */ @ReservedStackAccess protectedfinalbooleantryRelease(int releases) { if (!isHeldExclusively()) thrownewIllegalMonitorStateException(); intnextc= getState() - releases; booleanfree= exclusiveCount(nextc) == 0; if (free) setExclusiveOwnerThread(null); setState(nextc); return free; }
@ReservedStackAccess protectedfinalbooleantryAcquire(int acquires) { /* * Walkthrough: * 1. If read count nonzero or write count nonzero * and owner is a different thread, fail. * 2. If count would saturate, fail. (This can only * happen if count is already nonzero.) * 3. Otherwise, this thread is eligible for lock if * it is either a reentrant acquire or * queue policy allows it. If so, update state * and set owner. */ Threadcurrent= Thread.currentThread(); intc= getState(); intw= exclusiveCount(c); if (c != 0) { // (Note: if c != 0 and w == 0 then shared count != 0) if (w == 0 || current != getExclusiveOwnerThread()) returnfalse; if (w + exclusiveCount(acquires) > MAX_COUNT) thrownewError("Maximum lock count exceeded"); // Reentrant acquire setState(c + acquires); returntrue; } if (writerShouldBlock() || !compareAndSetState(c, c + acquires)) returnfalse; setExclusiveOwnerThread(current); returntrue; }
@ReservedStackAccess protectedfinalinttryAcquireShared(int unused) { /* * Walkthrough: * 1. If write lock held by another thread, fail. * 2. Otherwise, this thread is eligible for * lock wrt state, so ask if it should block * because of queue policy. If not, try * to grant by CASing state and updating count. * Note that step does not check for reentrant * acquires, which is postponed to full version * to avoid having to check hold count in * the more typical non-reentrant case. * 3. If step 2 fails either because thread * apparently not eligible or CAS fails or count * saturated, chain to version with full retry loop. */ Threadcurrent= Thread.currentThread(); // 当前状态 intc= getState(); // 独占锁被持有,并且独占的线程不是当前线程,直接获取失败失败 if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return -1; // 当前持有的共享锁的数量 intr= sharedCount(c); // 获取共享锁是否应该被阻塞&&共享锁数量小于最大值&&递增状态State成功. // 意味着加锁成功了. if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { // r==0意味着当前没有共享锁,那么当前线程就是第一个读线程,进行赋值 if (r == 0) { firstReader = current; firstReaderHoldCount = 1; } elseif (firstReader == current) { // 当前线程已经是第一个读线程了,对相关参数进行递增 firstReaderHoldCount++; } else { // 获取上一个读锁的获取者 HoldCounterrh= cachedHoldCounter; if (rh == null || rh.tid != LockSupport.getThreadId(current)) // 如果线程不是上一个线程,或者上一个缓存的为空 // 将当前的线程缓存起来 cachedHoldCounter = rh = readHolds.get(); elseif (rh.count == 0) // 当前线程就是缓存的上一个线程,但是数量为0. 就设置为readHold readHolds.set(rh); // 获取的读锁数量+1. rh.count++; } // 代表成功了. return1; } return fullTryAcquireShared(current); }
/** * Performs tryLock for write, enabling barging in both modes. * This is identical in effect to tryAcquire except for lack * of calls to writerShouldBlock. */ @ReservedStackAccess finalbooleantryWriteLock() { Threadcurrent= Thread.currentThread(); intc= getState(); if (c != 0) { intw= exclusiveCount(c); if (w == 0 || current != getExclusiveOwnerThread()) returnfalse; if (w == MAX_COUNT) thrownewError("Maximum lock count exceeded"); } if (!compareAndSetState(c, c + 1)) returnfalse; setExclusiveOwnerThread(current); returntrue; }
/** * Nonfair version of Sync */ staticfinalclassNonfairSyncextendsSync { privatestaticfinallongserialVersionUID= -8159625535654395037L; finalbooleanwriterShouldBlock() { returnfalse; // writers can always barge } finalbooleanreaderShouldBlock() { /* As a heuristic to avoid indefinite writer starvation, * block if the thread that momentarily appears to be head * of queue, if one exists, is a waiting writer. This is * only a probabilistic effect since a new reader will not * block if there is a waiting writer behind other enabled * readers that have not yet drained from the queue. */ return apparentlyFirstQueuedIsExclusive(); } }
主要是定义了父类中的两个抽象方法.
writerShouldBlock. 写锁的请求,任何时候都可以申请.
readerShouldBlock . 读锁的请求,能不能申请,要看情况咯.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * Returns {@code true} if the apparent first queued thread, if one * exists, is waiting in exclusive mode. If this method returns * {@code true}, and the current thread is attempting to acquire in * shared mode (that is, this method is invoked from {@link * #tryAcquireShared}) then it is guaranteed that the current thread * is not the first queued thread. Used only as a heuristic in * ReentrantReadWriteLock. */ finalbooleanapparentlyFirstQueuedIsExclusive() { Node h, s; return (h = head) != null && (s = h.next) != null && !s.isShared() && s.thread != null; }
publicfinalbooleanhasQueuedPredecessors() { Node h, s; if ((h = head) != null) { if ((s = h.next) == null || s.waitStatus > 0) { s = null; // traverse in case of concurrent cancellation for (Nodep= tail; p != h && p != null; p = p.prev) { if (p.waitStatus <= 0) s = p; } } // 队列中第一个在等待的节点,不是当前节点,那么当前线程就不要提交了 if (s != null && s.thread != Thread.currentThread()) returntrue; } // 当前节点的请求可以提交. returnfalse; }