Java并发包学习ReentrantReadWriteLock

一。概述

ReentrantReadWriteLock比synchronized更加灵活,更加面向对象。
ReentrantReadWriteLock实现了ReadWriteLock接口,ReadWriteLock接口包含两个方法:
Lock readLock();和Lock writeLock();

ReentrantReadWriteLock是个读写锁,即多个读锁不互斥,读锁和写锁互斥,这是由JVM控制的。

在ReentrantReadWriteLock中,有两个静态内部类:ReadLock和WriteLock,二者都继承自Lock接口。

注意ReentrantReadWriteLock中有个reentrant单词,是什么意思呢?字面意思是可重入。到底怎么个可重入法?

1)在WriteLock内部可获取ReadLock, 但在ReadLock内部不能获取WriteLock.
2)WriteLock可降级为ReadLock, 方法是先获得WriteLock在获得ReadLock, 然后再释放WriteLock. 这时候线程将持有ReadLock。而ReadLock则无法升级为WriteLock, 因为在ReadLock中无法获取WriteLock。
3)WriteLock和ReadLock都支持Interrupt。
4)WriteLock支持Condition, 而ReadLock不支持Condition.

那么什么叫做可重入?
就是一个线程可以重复加锁,可以对同一个锁加多次,每次释放的时候会释放一次,直到该线程加锁的次数为0,这个线程才释放锁。

什么叫做读写锁?
就是读锁可以共享,多个线程可同时拥有读锁;但写锁只能有一个线程拥有,而且获取写锁的时候,其他线程都要释放了读锁,而且在该线程获取了写锁之后,其他线程不能在获取读锁或写锁。

公平锁和非公平锁?
可在ReentrantReadWriteLock的构造器中指定公平读写锁和非公平读写锁。默认是非公平读写锁。

公平和非公平?
公平表示获取锁的顺序是按照线程的加锁顺序来分配锁,最早请求加锁的线程最先获得锁,即按照FIFO的顺序类分配锁;非公平锁表示获取锁的顺序是无序的,即无法保证先请求锁的线程就会先得到锁,这样可能导致某些线程可能一直没有获取到锁。

公平锁和非公平锁的性能?
公平锁性能不如非公平锁,因为公平锁需要在队尾排队并睡觉,然后等待被唤醒,这个睡觉和唤醒的过程是耗费性能的。

什么时候使用公平锁呢?
有多个读线程,一个写线程,且写线程的时候要阻塞读线程,这时需要使用公平锁,否则写线程可能一直等不到锁,导致写线程饿死。

二。ReentrantReadWriteLock的内部实现

ReentrantReadWriteLock是通过其内部类Sync来实现锁。实际上读、写锁只有一个锁,只是在获取读锁和写锁的方式上不一样。

ReentrantReadWriteLock里面有两个内部类ReadLock和WriteLock, 这两个类都是Lock的实现。只是他们的实现不同,WriteLock是互斥锁。

猜你喜欢

转载自blog.csdn.net/shijinghan1126/article/details/86500711