目前是下图的样子,线程1,2写锁都已经释放了,线程3加上读锁后还未释放,此时线程4来尝试加锁
仍然走的下面的代码 
    
tryAcquireShared,尝试加锁。
protected final int tryAcquireShared(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.
*/
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);
}
- exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current;条件不成立,进入下面的代码块
- int r = sharedCount(c);获取高16位的值,读锁加锁次数
- !readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)- readerShouldBlock() - 公平实现:就是判断一下有没有线程在等待着
- 非公平实现:返回true,意味着当前线程不是第一个排队的线程,同时队列中第一个等待的线程是独占模式的。返回false意味着前面没有写锁。
 
- r < MAX_COUNT,判断读锁加锁此时有没有超过可加锁的最大值
- compareAndSetState(c, c + SHARED_UNIT);用cas修改一下state值,表示加锁成功
 
- readerShouldBlock() 
- fullTryAcquireShared(current);,线程3cas时,线程4也来抢这个读锁,此时线程4是cas不成功的,就要执行当前这个方法。这个方法就是用于同时加读锁,有一个线程失败的情况下,去让加读锁失败的线程去for循环去加锁。- final int fullTryAcquireShared(Thread current) {
- /*
- * This code is in part redundant with that in
- * tryAcquireShared but is simpler overall by not
- * complicating tryAcquireShared with interactions between
- * retries and lazily reading hold counts.
- */
- HoldCounter rh = null;
- for (;;) {
- int c = getState();
- if (exclusiveCount(c) != 0) {
- if (getExclusiveOwnerThread() != current)
- return -1;
- // else we hold the exclusive lock; blocking here
- // would cause deadlock.
- } 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;
- }
- }
- }
 
 
                         
                                

