@adamhand
2019-01-22T13:40:24.000000Z
字数 2209
阅读 848
顾名思义,ReentrantReadWriteLock名为“可重入读写锁”,它维护两个锁:读锁和写锁。在没有写锁的情况下,读锁允许多个线程同时访问,而写锁是独占的,
ReentrantReadWriteLock主要特性有以下几个:
ReentrantReadWriteLock可以用来提高某些集合的并发性能。当集合比较大,并且读比写频繁时,可以使用该类。
读写锁的简单示例如下:
class Cache{
static Map<String, Object> map = new HashMap<String, Object>();
static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
static Lock r = rwLock.readLock();
static Lock w = rwLock.writeLock();
//获取一个key对应的value
public static final Object get(String key){
r.lock();
try {
return map.get(key);
}finally {
r.unlock();
}
}
//设置key对应的value值
public static final Object put(String key, Object value){
w.lock();
try {
return map.put(key, value);
}finally {
w.unlock();
}
}
//清空所有内容
public static final void clear(){
w.lock();
try {
map.clear();
}finally {
w.unlock();
}
}
}
锁降级的示例如下:
class LockDec{
static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
static Lock readLock = rwLock.readLock();
static Lock writeLock = rwLock.writeLock();
public volatile boolean update = false;
public void processData(){
readLock.lock();
if (!update){
//必须先释放读锁
readLock.unlock();
//锁降级从写锁获取到开始
writeLock.lock();
try {
if (!update){
//准备数据的流程
update = true;
}
readLock.lock();
}finally {
writeLock.unlock();
}
//锁降级完成,写锁降级为读锁
}
try {
//使用数据的流程
}finally {
readLock.unlock();
}
}
}
当数据发生变更后 ,update变量被设置为true,此时所有访问processData()方法的线程都能感知到变化。
ReentrantReadWriteLock底层也是使用AQS实现的,但是AQS中只有一个state域,这样就有了几个问题:
ReentrantReadWriteLock的解决办法总结起来有以下几个:
未完待续...
ReentrantReadWriteLock读写锁详解
JUC 可重入 读写锁 ReentrantReadWriteLock
【死磕Java并发】—–J.U.C之读写锁:ReentrantReadWriteLock
Java并发编程--ReentrantReadWriteLock
深入理解读写锁—ReadWriteLock源码分析
读写锁 ReetrantReadWriteLock