Java 读写锁¶
可同时读,读的时候不能写,写的时候不能读。读-写锁实现的加锁策略中,允许多个读操作同时进行,但每次只允许一个写操作。
使用ReentrantReadWriteLock
封装的Map
示例¶
ReentrantReadWriteLock
在构造时可以选择是否为公平锁。
这里给出一个ReentrantReadWriteLock
封装的Map
的示例。
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 使用ReentrantReadWriteLock封装的Map
*/
public class ReadWriteMap<K, V> {
private final Map<K, V> map; // 当然我们也可以封装一些别的集合类
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock r = lock.readLock();
private final Lock w = lock.writeLock();
public ReadWriteMap(Map<K, V> map) {
this.map = map;
}
public V put(K key, V value) {
w.lock();
System.out.println(Thread.currentThread() + " is putting."); // for debug
try {
return map.put(key, value);
} finally {
w.unlock();
}
}
public V get(Object key) {
r.lock();
try {
return map.get(key);
} finally {
r.unlock();
}
}
}
remove()
,putAll()
,clear()
等方法执行相同的操作。
测试代码
public class ReadWriteLockDemo {
public static void main(String[] args) {
final ReadWriteMap<String, String> map = new ReadWriteMap<>(new HashMap<>());
map.put("one", "init value");
for (int i = 1; i <= 4; i++) {
new WorkThread(map).start();
}
}
// 模拟工作的线程
static class WorkThread extends Thread {
private ReadWriteMap<String, String> map;
public WorkThread(ReadWriteMap<String, String> map) {
this.map = map;
}
@Override
public void run() {
for (int i = 1; i <= 2; i++) {
try {
System.out.println(this.toString() + " read out: " + map.get("one"));
map.put("one", this.toString() + System.currentTimeMillis());
Thread.sleep(2);
System.out.println(this.toString() + " read out: " + map.get("one"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/* 部分输出
Thread[main,5,main] is putting.
Thread[Thread-1,5,main] read out: init value
Thread[Thread-2,5,main] read out: init value
Thread[Thread-1,5,main] is putting.
Thread[Thread-2,5,main] is putting.
Thread[Thread-3,5,main] read out: Thread[Thread-2,5,main]1536664817446
Thread[Thread-3,5,main] is putting.
Thread[Thread-0,5,main] read out: Thread[Thread-3,5,main]1536664817446
Thread[Thread-0,5,main] is putting.
Thread[Thread-2,5,main] read out: Thread[Thread-0,5,main]1536664817447
Thread[Thread-2,5,main] read out: Thread[Thread-0,5,main]1536664817447
Thread[Thread-3,5,main] read out: Thread[Thread-0,5,main]1536664817447
*/
ReentrantLock不能完全替代synchronized,只有在synchronized无法满足需求时,才应该使用它。
读-写锁允许多个读线程并发地访问被保护的对象,当访问以读取操作为主的数据结构时, 它能提高程序的可伸缩性。
参考¶
- 《Java并发编程实战》 Java Concurrency in Practice
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~