ReentrantReadWriteLock実現原理
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
readLock.lock();
sync.acquireShared(1);
1.tryAcquireShared(arg)
1. , ,
2. , cas ,
2.1 , 1, firstReader firstReaderHolderCount 1
2.2 r 0 firstReader firstReaderHolderCount 1
2.3
2.4 1
3.2 fullTryAcquireShared(). TryAcquireShared() , ,
4. doAcquireShared(arg)
2.doAcquireShared(arg);
1.addWaiter(Node.SHARED);
1. Node
2. tail head , , node
3. tail null, node
2. .
3. head,
1. tryAcquireShared(arg); .
2. setHeadAndPropagate()
3.setHeadAndPropagate(node, r);
1. head , ( )
2. propagate >0 , doReleaseShared();
3.doReleaseShared();
1.
2. head null head tail , head waitstatus Signal( ). cas head 0 unpark head next
3. waitstatus 0( ), head PROPAGATE( , )
4.unpark
4. head next null( gc )
5. interrupted true selfInterrupt();
6. failed false
7. ;
4. shouldParkAfterFailedAcquire(p, node)
1. SIGNAL
2. CANCELLED
3. SIGNAL
5. true parkAndCheckInterrupt()
1.park
2. interrupted
6. true interrupted true
7. finally failed true cancelAcquire(node);. selfInterrupt() ;
1.node=null
2.node thread null
3. node pre CANCELLED ,
4. node CANCELLED
5. node tail . cas tail pre , pred next null( tail next )
6. tail head , cas node
7. head unparkSuccessor(node),
8. node.next , gc
readLock.unlock();
sync.releaseShared(1);
1. tryReleaseShared(arg)
1. firstReader
1. firstReaderHoldCount==1, firstReader null, 1
2. firstReaderHoldCount--;
2.firstReader
1. cachedHoldCounter , threadLocal id key
2. cachedHoldCounter , cachedHoldCounter , readHolds.get() .
3. HoldCounter count ,
1. 1 readHolds
2. count 0, .
4. --count
3.
1. state
2. , cas
3. ==0
2. true doReleaseShared()( ); TRUE
3. false
ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
writeLock.lock()
sync.acquire(1);
1. tryAcquire(arg)
1. state
2. state ( state( )
3. state 0
1. 0( 0). false
2. ,
3. setState ( , cas
4. true
4. writerShouldBlock() ,
1. hasQueuedPredecessors
2. false,
5. true, cas , false
6. , setExclusiveOwnerThread(current);,
7. true
2. acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
1. addWaiter(Node.EXCLUSIVE) ,
2.failed true
3.interrupted false;
4.
1. head, tryAcquire(arg)
1. , node head, ,
2. head next null
3.failed false
4. interrupted . false;
2. , shouldParkAfterFailedAcquire
3. parkAndCheckInterrupt()
4. parkAndCheckInterrupt() true interrupted true
5.
5. finally failed true cancelAcquire(node);
writeLock.unlock()
sync.release(1);
1. tryRelease(arg)
1. isHeldExclusively
1.return getExclusiveOwnerThread() == Thread.currentThread();
2. nextc ( )
3. free = exclusiveCount(nextc) == 0
4. (free true) setExclusiveOwnerThread null
5. state nextc
6. free
2. , unparkSuccessor true. .
3. false, ,