美文网首页
ReentrantReadWriteLock源码解析(2)loc

ReentrantReadWriteLock源码解析(2)loc

作者: 三斤牛肉 | 来源:发表于2021-01-28 15:00 被阅读0次

    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)loc

          本文链接:https://www.haomeiwen.com/subject/ppidaktx.html