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

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

文章首发于: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());
        }

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


来源:https://www.jianshu.com/p/347ea7f881f8

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » 【锁】ReentrantReadWriteLock之读写锁公平性体现源码分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏