概念
读写锁ReentrantReadWriteLock,其核心就是实现读写分离的锁。在高并发访问下,尤其是读多写少的情况下,其性能要远高于重入锁。
synchronized,ReentrantLock,我们知道在同一时间内只能有一个线程进行访问被锁定的代码,那么读写锁则不同,其本质是分成两个锁,即读锁、写锁。在读锁下,多个线程可以并发的进行访问,但是在写锁的时候,只能一个一个的顺序访问。
这里有一个小口诀:读读共享,写写互斥,读写互斥。
事例
先看读读共享
public class UseReentrantReadWriteLock {
private ReentrantReadWriteLock rwLock=new ReentrantReadWriteLock();
private ReadLock rLock=rwLock.readLock();
private WriteLock wLock=rwLock.writeLock();
public void read(){
try {
rLock.lock();
System.out.println("当前线程:"+Thread.currentThread().getName()+"进入");
Thread.sleep(3000);
System.out.println("当前线程:"+Thread.currentThread().getName()+"退出");
} catch (Exception e) {
e.printStackTrace();
}finally {
rLock.unlock();
}
}
public void write(){
try {
wLock.lock();
System.out.println("当前线程:"+Thread.currentThread().getName()+"进入");
Thread.sleep(3000);
System.out.println("当前线程:"+Thread.currentThread().getName()+"退出");
} catch (Exception e) {
e.printStackTrace();
}finally {
wLock.unlock();
}
}
public static void main(String[] args) {
final UseReentrantReadWriteLock urrw=new UseReentrantReadWriteLock();
Thread t1=new Thread(new Runnable(){
@Override
public void run() {
urrw.read();
}
},"t1");
Thread t2=new Thread(new Runnable(){
@Override
public void run() {
urrw.read();
}
},"t2");
Thread t3=new Thread(new Runnable(){
@Override
public void run() {
urrw.write();
}
},"t3");
Thread t4=new Thread(new Runnable(){
@Override
public void run() {
urrw.write();
}
},"t4");
//读读共享
t1.start();
t2.start();
}
}
运行结果:t1,t2同时进入,然后同时退出。
接下来是读写互斥,我们只需要启动t1,t3两个线程即可,其他代码不变
t1.start();
t3.start();
运行结果:t1线程进入并退出后,t3线程才能进入并退出
最后是写写互斥,我们启动t3,t4线程
t3.start();
t4.start();
运行结果:t3线程进入并退出后,t4线程才能进入并退出