ReentrantReadWriteLock源码解析(2)lock

ReentrantReadWriteLock中有2个对象ReadLock,WriteLock分别都有lock函数:
readlock.lock()

public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
}

protected final int tryAcquireShared(int unused) {
            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)) {//且cas成功,表示获得到读锁
                //下面这一大段都是缓存,提高执行效率,可以看上一节
                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);
        }

readerShouldBlock分别在公平锁和非公平锁中:
FairSync.readerShouldBlock

final boolean readerShouldBlock() {
           //看队列中是否有排队的线程,公平锁中只要前面有人在排队那么当前线程就应该被阻塞,不能去竞争锁,必须进入排队
            return hasQueuedPredecessors();
        }

NonfairSync.readerShouldBlock

final boolean readerShouldBlock() {
         //队列中第一个排队的线程(队列中第二个元素)是写线程
           //非公平锁中,如果第一个排队的是写,那么不能去竞争;如果是读,读读是共享的,而且是非公平,那么就可以去抢一下
            return apparentlyFirstQueuedIsExclusive();
        }

你可能感兴趣的:(ReentrantReadWriteLock源码解析(2)lock)