ReentrantReadWriteLock,谓之读写分离锁。很多情况下,线程可能都只是读取资源,这并不会对资源进行更改或者破坏,但如果这样也要阻塞等待的话,显然很不合理和高效,于是有了读写分离锁,读写分离锁可以有效地减少锁竞争,提升程序性能。其实读写分离这种理念在Mysql、redis等数据库的主从复制也应用很多,目的一样,都是为了提升系统性能。
读写锁的互相约束如下:
- 读-读:不互斥不阻塞。
- 读-写:互斥阻塞。
- 写-写:互斥阻塞。
ReentrantReadWriteLock实现了接口ReadWriteLock,该接口声明了只读锁和写锁两个方法。源码如下:
public interface ReadWriteLock {
Lock readLock();
Lock writeLock();
}
ReentrantReadWriteLock实现了这两个方法,源码如下:
//无参构造方法,默认为非公平锁
public ReentrantReadWriteLock() {
this(false);
}
//带参构造方法,可以设置锁竞争是否公平
public ReentrantReadWriteLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();//这句是不是很眼熟?几乎所有的锁都是这样的
readerLock = new ReadLock(this);//读锁
writerLock = new WriteLock(this);//写锁
}
//获取读锁和写锁
public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
我们分别对读写锁进行使用,示例如下:
public class ReentrantReadWriteLockTest {
private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private static Lock writeLock = reentrantReadWriteLock.writeLock();
private static Lock readLock = reentrantReadWriteLock.readLock();
public static class Read implements Runnable{
@Override
public void run() {
try {
readLock.lock();
System.out.println(Thread.currentThread().getName()+" 获取锁");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+" 释放锁");
readLock.unlock();
}
}
}
public static class Write implements Runnable{
@Override
public void run() {
try {
writeLock.lock();
System.out.println(Thread.currentThread().getName()+" 获取锁");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+" 释放锁");
writeLock.unlock();
}
}
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(new Read(),"读锁"+i).start();
}
for(int i=0;i<10;i++){
new Thread(new Write(),"写锁"+i).start();
}
}
}
结果:

结果
为了结果短一点,我们把读写的线程数都设为了3,从结果可以看到,读锁都先拿到了锁的许可,并没有阻塞。而写锁只有在上一个线程释放锁后才有机会获取锁的许可。