背景:
对数据的访问一般只有两种情况:
1.读数据
2.写数据
一般的锁并不能区分是哪种目的,但如果仅仅是读操作,并不会有并发问题。多次的阻塞也会带来性能的损失,因此读写锁应运而生
使用:
1.自定义定义数据容器
2.分别获得读锁和写锁
3.对读,写方法分别加上对应的锁
import java.util.concurrent.locks.ReentrantReadWriteLock;
class DataContainer{
private Object data;
private ReentrantReadWriteLock rw=new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock r= rw.readLock();
private ReentrantReadWriteLock.WriteLock w= rw.writeLock();
public Object read(){
r.lock();
try {
Thread.sleep(1000);
System.out.println("读取。。。。。。。。。。。。");
return data;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
r.unlock();
}
}
public void write(){
w.lock();
try {
Thread.sleep(1000);
System.out.println("写入。。。。。。。。。。。");
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
w.unlock();
}
}
}
注意事项:
读写锁不支持已经获得读锁,再去获得写锁(读写互斥,会一直等待下去),但支持先获得写锁,再获取读锁(我读我自己)
与ReentrantLock差别:
读写锁看似是两把,实际上共用一个AQS的state,读锁使用高16位,写锁使用低16位