- 允许多个线程同时读共享变量。
- 只允许一个线程写共享变量。
- 如果一个线程正在执行写操作,此时禁止读线程读共享变量。
- 总结: 读-读可以,读-写互斥,写-写互斥。
- 注意:写锁可降级为读锁,读锁不能升级为写锁。
- 简单使用示例
public class ReentranReadWriteLokeDemo<K, V> {
private final Map<K, V> map = new HashMap<K, V>();
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
final Lock writeLock = readWriteLock.writeLock();
final Lock readLock = readWriteLock.readLock();
public V get(K k) {
readLock.lock();
try {
return map.get(k);
} finally {
readLock.unlock();
}
}
public V put(K k, V v) {
writeLock.lock();
try {
return map.put(k, v);
}finally {
writeLock.unlock();
}
}
}
- 注意避免锁的升级,此时读锁还未释放,去获取写锁,会导致锁永久等待,最终导致相关线程都被阻塞,永远没有机会呗唤醒。如下示例你可以复制代码测试下,线程会一直等待下去:
public class ReentranReadWriteLokeDemo {
public static void main(String[] args) {
ReentranReadWriteLokeTest reentranReadWriteLokeTest = new ReentranReadWriteLokeTest();
Object value = reentranReadWriteLokeTest.get("one");
System.out.println(value);
}
private static class ReentranReadWriteLokeTest<K, V> {
private final Map<K, V> map = new HashMap<K, V>();
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
final Lock writeLock = readWriteLock.writeLock();
final Lock readLock = readWriteLock.readLock();
public V get(K k) {
readLock.lock();
try {
V v = map.get(k);
if (v == null) {
writeLock.lock();
try {
System.out.println("执行写操作");
}finally {
writeLock.unlock();
}
}
return v;
} finally {
readLock.unlock();
}
}
public V put(K k, V v) {
writeLock.lock();
try {
return map.put(k, v);
}finally {
writeLock.unlock();
}
}
}
}
- 锁的降级是被允许的,如下代码,获取读锁的时候还持有写锁。
public static void main(String[] args) {
ReentranReadWriteLokeTest reentranReadWriteLokeTest = new ReentranReadWriteLokeTest();
reentranReadWriteLokeTest.put("one", "value");
}
private static class ReentranReadWriteLokeTest<K, V> {
private final Map<K, V> map = new HashMap<K, V>();
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
final Lock writeLock = readWriteLock.writeLock();
final Lock readLock = readWriteLock.readLock();
public V get(K k) {
readLock.lock();
try {
V v = map.get(k);
return v;
} finally {
readLock.unlock();
}
}
public void put(K k, V v) {
writeLock.lock();
try {
V value = map.put(k, v);
if (value == null) {
readLock.lock();
try {
System.out.println("添加的value为:"+ map.get(k));
}finally {
readLock.unlock();
}
}
}finally {
writeLock.unlock();
}
}
}
}