change lock

This commit is contained in:
Looly 2021-01-24 22:37:12 +08:00
parent a8add399c2
commit bdb078b1ee
3 changed files with 19 additions and 9 deletions

View File

@ -14,6 +14,7 @@
* 【core 】 修正LocalDateTimeUtil.offset方法注释问题issue#I2EEXC@Gitee
* 【extra 】 VelocityEngine的getRowEngine改为getRawEngineissue#I2EGRG@Gitee
* 【cache 】 缓存降低锁的粒度提高并发能力pr#1385@Github
* 【core 】 SimpleCache缓存降低锁的粒度提高并发能力pr#1385@Github
### Bug修复
* 【core 】 修复FileUtil.move以及PathUtil.copy等无法自动创建父目录的问题issue#I2CKTI@Gitee

View File

@ -150,7 +150,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
final Lock keyLock = keyLockMap.computeIfAbsent(key, k -> new ReentrantLock());
keyLock.lock();
try {
// 双重检查锁
// 双重检查锁防止在竞争锁的过程中已经有其它线程写入
final CacheObj<K, V> co = cacheMap.get(key);
if (null == co || co.isExpired()) {
try {

View File

@ -6,6 +6,9 @@ import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
@ -24,6 +27,10 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
private final Map<K, V> cache;
// 乐观读写锁
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
/**
* 写的时候每个key一把锁降低锁的粒度
*/
protected final Map<K, Lock> keyLockMap = new ConcurrentHashMap<>();
/**
* 构造默认使用{@link WeakHashMap}实现缓存自动清理
@ -70,22 +77,24 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
*/
public V get(K key, Func0<V> supplier) {
V v = get(key);
if(null == v && null != supplier){
lock.writeLock().lock();
try{
v = cache.get(key);
//每个key单独获取一把锁降低锁的粒度提高并发能力see pr#1385@Github
final Lock keyLock = keyLockMap.computeIfAbsent(key, k -> new ReentrantLock());
keyLock.lock();
try {
// 双重检查防止在竞争锁的过程中已经有其它线程写入
v = cache.get(key);
if (null == v) {
try {
v = supplier.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
cache.put(key, v);
put(key, v);
}
} finally{
lock.writeLock().unlock();
} finally {
keyLock.unlock();
keyLockMap.remove(key);
}
}
@ -143,4 +152,4 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
public Iterator<Map.Entry<K, V>> iterator() {
return this.cache.entrySet().iterator();
}
}
}