读写锁
腾讯文档 共享协作
可读可写权限。如何实现多人写?即不加写锁?
互斥锁,写独占,读共享
只可一人独自写存,多人可同时读取,共享。
使用前
排它锁和共享锁同时使用后
/**
* 只有一个线程写,多个线程读。使用ReadWriteLock读写锁
* “读锁”是否去锁 共享锁
* “写锁”是否去锁 独占锁
* 互斥锁,写独占,读共享
* @Author Weton Li
* @Date 2021/2/10 17:52
*/
public class ReadWriteLockDemo {
public static void main(String[] args) {
// MyCache myCache = new MyCache();
MyCacheLock myCacheLock = new MyCacheLock();
/*写*/
for (int i = 1; i <= 5; i++) {
final int temp = i;
new Thread(() -> {
// myCache.put(temp + "", temp + ""); // 5个线程读
myCacheLock.put(temp + "", temp + ""); // 5个线程读
}, String.valueOf(i)).start();
}
/*读*/
for (int i = 1; i <= 5; i++) {
final int temp = i;
new Thread(() -> {
// myCache.get(temp + ""); // 5个线程写
myCacheLock.get(temp + ""); // 5个线程写
}, String.valueOf(temp)).start();
}
}
}
class MyCacheLock {
private volatile Map<String, Object> map = new HashMap<>();
// 创建可重用读写锁,更加细粒度的控制
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
/*只能有一人写*/
public void put(String key, Object value) {
readWriteLock.writeLock().lock(); // 上"写锁"
try {
System.out.println(Thread.currentThread().getName() + "存写入");
map.put(key, value);
System.out.println("写入成功");
}catch (Exception e){
e.printStackTrace();
}finally {
readWriteLock.writeLock().unlock(); // 解"写锁"
}
}
/*多人同时读*/
public void get(String key) {
readWriteLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "取读出");
map.get(key);
System.out.println("读取成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
/**
* 未加锁的缓存
*/
class MyCache {
private volatile Map<String, Object> map = new HashMap<>();
// 存 写
public void put(String key, Object value) {
System.out.println(Thread.currentThread().getName() + "存写入");
map.put(key, value);
System.out.println("写入成功");
}
// 取 读
public void get(String key) {
System.out.println(Thread.currentThread().getName() + "取读出");
Object o = map.get(key);
System.out.println("读取成功");
}
}