ReentrantCache修改get逻辑key锁改为全局锁,保证安全。(issue#4022@Github)

This commit is contained in:
Looly
2025-08-26 16:19:57 +08:00
parent fbfcafe54f
commit d0094e43b5
2 changed files with 2 additions and 21 deletions

View File

@@ -22,7 +22,7 @@
* 【extra 】 修复`QLExpressEngine`allowClassSet无效问题issue#3994@Github
* 【core 】 修复`StrBuilder`insert插入计算错误问题issue#ICTSRZ@Gitee
* 【cron 】 修复`CronPatternUtil.nextDateAfter`计算下一个匹配表达式的日期时计算错误问题issue#4006@Github
* 【cache 】 `ReentrantCache`增加`setUseKeyLock`让用户选择是否使用键锁来增强性能,或者保证安全。issue#4022@Github
* 【cache 】 `ReentrantCache`修改get逻辑key锁改为全局锁保证安全。issue#4022@Github
-------------------------------------------------------------------------------------------------------------
# 5.8.39(2025-06-20)

View File

@@ -25,20 +25,6 @@ public abstract class ReentrantCache<K, V> extends AbstractCache<K, V> {
// TODO 最优的解决方案是使用Guava的ConcurrentLinkedHashMap此处使用简化的互斥锁
protected final ReentrantLock lock = new ReentrantLock();
private boolean useKeyLock = true;
/**
* 设置是否使用key锁默认为true
*
* @param useKeyLock 是否使用key锁
* @return this
* @since 5.8.40
*/
public ReentrantCache<K, V> setUseKeyLock(boolean useKeyLock) {
this.useKeyLock = useKeyLock;
return this;
}
@Override
public void put(K key, V object, long timeout) {
lock.lock();
@@ -61,11 +47,6 @@ public abstract class ReentrantCache<K, V> extends AbstractCache<K, V> {
@Override
public V get(final K key, final boolean isUpdateLastAccess, final long timeout, final Func0<V> valueFactory) {
if(useKeyLock){
// 用户如果允许则使用key锁可以减少valueFactory对象创建造成的
return super.get(key, isUpdateLastAccess, timeout, valueFactory);
}
V v = get(key, isUpdateLastAccess);
// 对象不存在,则加锁创建
@@ -80,7 +61,7 @@ public abstract class ReentrantCache<K, V> extends AbstractCache<K, V> {
if (null == co) {
// supplier的创建是一个耗时过程此处创建与全局锁无关而与key锁相关这样就保证每个key只创建一个value且互斥
v = valueFactory.callWithRuntimeException();
put(key, v, timeout);
putWithoutLock(key, v, timeout);
}
} finally {
lock.unlock();