美文网首页
ReentrantReadWriteLock读写锁

ReentrantReadWriteLock读写锁

作者: 断忆残缘 | 来源:发表于2021-02-20 17:03 被阅读0次

    ReentrantReadWriteLock写锁尝试获取锁

    protected final boolean tryAcquire(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.
         */
        Thread current = Thread.currentThread();
        // 获取锁的状态
        int c = getState();
        // 获取锁中写的状态
        int w = exclusiveCount(c);
        /**
         * 如果c不为0,说明锁已经被某个线程持有,当然有可能是当前线程(重入)。
         */
        if (c != 0) {
            // (Note: if c != 0 and w == 0 then shared count != 0)
            /**
             * w == 0, 说明没有写锁,即使是当前线程持有,无法获取到锁,
             * 因为锁不支持升级,所以返回false
             *
             * 走到第二个条件,说明是有写锁
             * 判断重入:current != getExclusiveOwnerThread()
             * 判断时否为当前线程,如果不是,则返回false
             */
            if (w == 0 || current != getExclusiveOwnerThread())
                return false;
            /**
             * 判断是否大于最大重入次数,最大次数:2^16-1
             */
            if (w + exclusiveCount(acquires) > MAX_COUNT)
                throw new Error("Maximum lock count exceeded");
            // Reentrant acquire
            // 锁的次数+1(state:readLock(16位2进制)| writeLock(16位2进制))
            setState(c + acquires);
            return true;
        }
      
        /**
         * c == 0 没有被人持有
         * writerShouldBlock()作用:判断是否需要排队,通过队列中是否存在线程
         * 1.非公平锁,不管是否有线程排队,都返回false(不需要排队)
         * 2.公平锁,判断队列中是否存在线程,如果有,就排队。
         *   (跳过第二条执行,直接返回false);反之(执行第二条语句)
         *
         * !compareAndSetState(c, c + acquires)作用:获取锁,如果获取不到锁,返回false
         */
        if (writerShouldBlock() ||
            !compareAndSetState(c, c + acquires))
            return false;
        // 加锁成功,把锁中的线程,设置为当前线程。
        setExclusiveOwnerThread(current);
        return true;
    }
    

    相关文章

      网友评论

          本文标题:ReentrantReadWriteLock读写锁

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