ReentrantReadWriteLock读写锁的使用
ReentrantReadWriteLock里一共有两把锁,一把读锁,一把写锁;
读写锁使用场景:适合读次数多写次数少的场景。
1、线程进入读锁和写锁的前提条件:
线程进入读锁的前提条件:
没有其他写锁;
没有写的请求或者有写的请求,但是和持有锁得线程是同一个线程。
线程进入写锁的前提条件:
没有任何(包括当前线程)线程的读锁;
没有其他线程的写锁。
首先先区分一下ReentrantReadWriteLock和ReentrantLock,这两个类没有一毛钱关系,我们可以看到ReentrantReadWriteLock实现的是ReadWriteLock接口,而ReentrantLock类实现的是Lock接口,因此两者没有任何关系,但是ReentrantReadWriteLock类中的ReadLock和WriteLock变量也是实现了Lock接口。
2、ReentrantReadWriteLock锁机制的特性:
A、锁重入方面,当一个线程获得了WriteLock,也就可以获取ReadLock,但是反过来当一个线程获得了ReadLock,想要获取WriteLock却永远都不可以。
B、WriteLock 可以降级为ReadLock,但是ReadLock却不能升级为WriteLock(参照A特性),WriteLock降级为ReadLock:一个线程获得了WriteLock,再去获得ReadLock,然后就会释放WriteLock,这个时候线程将保持ReadLock的持有,称为降级。
C、ReadLock可以被多个线程同时持有,与WriteLock进行互斥,而WriteLock只能被一个线程持有,且与所有的ReadLock形成互斥。
D、ReadLock和WriteLock都支持interrupt,语义与ReentrantLock一样。
E、WriteLock支持Condition并且与ReentrantLock语义一致,而ReadLock则不可以使用Condition否则将抛出异常。
Eg:
控制台输出:
以上的例子说明了(1)读锁可以被多个线程同时访问,但是这些线程在访问读锁的同时,其他线程不可以访问写锁;(2)写锁只能被一个线程访问,并与读锁形成互斥。
使用读写锁实现简单的缓存管理器Eg: