并发编程-读写锁ReentrantReadWriteLock的公平和非公平区别在哪里

之前发过一篇文章讲了可重入锁的公平和非公平的区别,读写锁则不做过多赘述

并发编程-可重入锁ReentrantLock的公平和非公平区别在哪里?

读写锁的公平和非公平的区别与ReentrantLock的类似都是在锁的获取上

写锁的获取

无论是公平还是非公平写锁在获取的时候都会走的一个方法writerShouldBlock

//       非公平情况下
        final boolean writerShouldBlock() {
            return false; // writers can always barge
        }
//      公平情况下
        final boolean writerShouldBlock() {
//            检测同步队列中是否有节点,有节点则返回true
            return hasQueuedPredecessors();
        }

非公平情况下写锁会直接尝试获取,而公平情况下会检测同步队列中是否存在节点,存在则返回true,然后当前线程会被扔进队尾。

读锁的获取

无论是公平还是非公平写锁在获取的时候都会走的一个方法readerShouldBlock

//      公平情况下
        final boolean readerShouldBlock() {
            return hasQueuedPredecessors();
        }
//       非公平情况下
        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.
             */
            return apparentlyFirstQueuedIsExclusive();
        }

公平情况下和写锁的获取一样检测有没有节点有的话直接插入队尾,非公平情况下,它会检测下一个节点是不是写线程是的话则插入队尾,不是的话则尝试获取,这样做的目的防止写线程长时间处于饥饿状态。

总结

在读写锁中,写锁的优先级是要高于读锁的,但是非公平情况下:假如开始有2个写线程竞争有一个肯定会被扔进队列中,但是读线程在获取锁的时候会直接尝试拿读锁,拿锁成功则执行业务,如果此时有多个读线程一直拿锁,则同步队列中的写线程会一直处于饥饿状态。所以非公平情况下读锁是这样处理的。

 

© 版权声明
THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发