使用JDK原生的ReentrantLock读写锁解决写操作并发问题
ReentrantLockDemo
测试类
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCache myCache = new MyCache();
for (int i = 1; i <= 5; i++) {
final int it = i;
new Thread(() ->{
myCache.set(it+"key",it+"value");
},String.valueOf(i)).start();
new Thread(() ->{
myCache.get(it+"key");
},String.valueOf(i)).start();
}
}
}
资源类(加锁之前)
class MyCache1 {
Map<String, Object> map = new HashMap<>();
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public void set(String key, Object value) {
System.out.println(Thread.currentThread().getName() + "正在写入" + key);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
map.put(key, value);
System.out.println(Thread.currentThread().getName() + "写入完成");
}
public void get(String key) {
System.out.println(Thread.currentThread().getName() + "正在读取" + key);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
Object result = map.get(key);
System.out.println(Thread.currentThread().getName() + "读取结果:" + result);
}
}
测试结果:

写操作应该具有原子性,写操作不能与写操作并发,也不能与读并发。但是测试结果显示,写操作与其他的写操作或者读操作并发执行了。那么我们对资源类进行改造:
资源类(加锁之后)
class MyCache {
Map<String, Object> map = new HashMap<>();
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public void set(String key, Object value) {
try {
rwLock.writeLock().lock();
System.out.println(Thread.currentThread().getName() + "正在写入" + key);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
map.put(key,value);
System.out.println(Thread.currentThread().getName() + "写入完成");
} finally {
rwLock.writeLock().unlock();
}
}
public void get(String key) {
try {
rwLock.readLock().lock();
System.out.println(Thread.currentThread().getName() + "正在读取" + key);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
Object result = map.get(key);
System.out.println(Thread.currentThread().getName() + "读取结果:" +result);
} finally {
rwLock.readLock().unlock();
}
}
}
测试结果:

测试结果显示完美,写与写操作不能并发,写与读不能并发,读与读可以并发。
测试结果对比:

测试结果显示完美,写与写操作不能并发,写与读不能并发,读与读可以并发。
源码及其他并发demo见github
本文通过实例展示了如何使用JDK的ReentrantReadWriteLock解决并发编程中的写操作并发问题。在未加锁的情况下,写操作与其他写操作或读操作并发执行,导致数据不一致。通过为资源类的`set`和`get`方法添加读写锁,确保了写操作的原子性,实现了写与写互斥,写与读互斥,读与读可并发的效果,从而保证了数据的一致性和并发安全性。
9万+

被折叠的 条评论
为什么被折叠?



