【锁】ReentrantReadWriteLock之读写锁公平性体现源码分析

文章首发于:clawhub.club


ReentrantReadWriteLock的公平性体现在Sync的两个子类NonfairSync和FairSync重写的Sync中的两个方法:

/**
         * Returns true if the current thread, when trying to acquire
         * the read lock, and otherwise eligible to do so, should block
         * because of policy for overtaking other waiting threads.
         * 如果当前线程在尝试获取读锁时阻塞,并且由于策略原因无法超过其他等待的线程,
         * 因此有资格阻塞读锁,则返回true。
         */
        abstract boolean readerShouldBlock();

        /**
         * Returns true if the current thread, when trying to acquire
         * the write lock, and otherwise eligible to do so, should block
         * because of policy for overtaking other waiting threads.
         * 如果当前线程在尝试获取写锁时阻塞,并且由于策略原因无法超过其他等待的线程,
         * 因此有资格这样做,则返回true。
         */
        abstract boolean writerShouldBlock();

readerShouldBlock方法使用的地方为共享模式锁的获取,writerShouldBlock使用的地方为独占模式锁的获取。

NonfairSync

  final boolean writerShouldBlock() {
            // writers can always barge
            //非公平模式下,写锁的获取,当发生阻塞的时候,返回false
            return false;
        }

写锁在非公平模式,在非重入的前提下永远获取锁失败。

final boolean readerShouldBlock() {
            /* As a heuristic to avoid indefinite writer starvation,
             * block if the thread that momentarily appears to be head
             * of queue, if one exists, is a waiting writer.  This is
             * only a probabilistic effect since a new reader will not
             * block if there is a waiting writer behind other enabled
             * readers that have not yet drained from the queue.
             * 作为一种避免无限writer饥饿的启发式方法,
             * 如果暂时出现队列头的线程(如果存在)是一个正在等待的writer,则阻塞。
             * 这只是一种概率效应,因为如果在其他启用的reader后面有一个等待的writer,
             * 而这些reader还没有从队列中删除,则新reader不会阻塞。
             */
            return apparentlyFirstQueuedIsExclusive();
        }
   final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
            (s = h.next)  != null &&
            !s.isShared()         &&
            s.thread != null;
    }

读锁在非公平模式下,同步队列中最少为两个节点,且当前节点不是共享模式,且节点的线程不为null,就阻塞获取锁。

FairSync

 final boolean writerShouldBlock() {
            return hasQueuedPredecessors();
        }

        final boolean readerShouldBlock() {
            return hasQueuedPredecessors();
        }
 public final boolean hasQueuedPredecessors() {
        // The correctness of this depends on head being initialized
        // before tail and on head.next being accurate if the current
        // thread is first in queue.
        Node t = tail; // Read fields in reverse initialization order
        Node h = head;
        Node s;
        return h != t &&
            ((s = h.next) == null || s.thread != Thread.currentThread());
    }

公平模式下,读锁与写锁都要看自己是不是将要获取锁的同步队列节点,如果不是,就阻塞。

你可能感兴趣的:(【锁】ReentrantReadWriteLock之读写锁公平性体现源码分析)