mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
change lock
This commit is contained in:
parent
a8add399c2
commit
bdb078b1ee
@ -14,6 +14,7 @@
|
||||
* 【core 】 修正LocalDateTimeUtil.offset方法注释问题(issue#I2EEXC@Gitee)
|
||||
* 【extra 】 VelocityEngine的getRowEngine改为getRawEngine(issue#I2EGRG@Gitee)
|
||||
* 【cache 】 缓存降低锁的粒度,提高并发能力(pr#1385@Github)
|
||||
* 【core 】 SimpleCache缓存降低锁的粒度,提高并发能力(pr#1385@Github)
|
||||
|
||||
### Bug修复
|
||||
* 【core 】 修复FileUtil.move以及PathUtil.copy等无法自动创建父目录的问题(issue#I2CKTI@Gitee)
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user