修复AbstractCacheputWithoutLock方法可能导致的外部资源泄露问题(pr#3958@Github)

This commit is contained in:
Looly 2025-06-20 17:34:24 +08:00
parent a60c70ca86
commit a504fa860c
3 changed files with 12 additions and 17 deletions

View File

@ -24,6 +24,7 @@
* 【core 】 修复`ClassUti`isNormalClass判断未排除String问题issue#3965@Github
* 【core 】 修复`ZipUtil`中zlib和unZlib调用后资源未释放问题issue#3976@Github
* 【core 】 修复`Money`类的setAmount方法没有获取当前币种的小数位数而是使用的默认小数位和在遇到非2小数位的币种(如日元使用 0 位)会导致金额设置错误问题pr#3970@Github
* 【cahce 】 修复`AbstractCache`putWithoutLock方法可能导致的外部资源泄露问题pr#3958@Github
-------------------------------------------------------------------------------------------------------------
# 5.8.38(2025-05-13)

View File

@ -88,12 +88,10 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
final MutableObj<K> mKey = MutableObj.of(key);
// issue#3618 对于替换的键值对不做满队列检查和清除
if (cacheMap.containsKey(mKey)) {
CacheObj<K, V> oldObj = cacheMap.get(mKey);
if (oldObj != null) {
onRemove(oldObj.key, oldObj.obj);
cacheMap.remove(mKey);
}
final CacheObj<K, V> oldObj = cacheMap.get(mKey);
if (null != oldObj) {
onRemove(oldObj.key, oldObj.obj);
// 存在相同key覆盖之
cacheMap.put(mKey, co);
} else {
if (isFull()) {

View File

@ -4,13 +4,13 @@ import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.jupiter.api.Assertions.*;
/**
* 缓存测试用例
*
@ -155,19 +155,15 @@ public class CacheTest {
*/
@Test
public void reentrantCache_clear_Method_Test() {
Cache<String, String> lruCache = CacheUtil.newLRUCache(4);
lruCache.setListener(new CacheListener<String, String>() {
@Override
public void onRemove(String key, String cachedObject) {
System.out.println(" listener key= "+ key+" value = "+cachedObject.toString()+" cachedObject资源释放操作...");
}
} );
final AtomicInteger removeCount = new AtomicInteger();
final Cache<String, String> lruCache = CacheUtil.newLRUCache(4);
lruCache.setListener((key, cachedObject) -> removeCount.getAndIncrement());
lruCache.put("key1","String1");
lruCache.put("key2","String2");
lruCache.put("key3","String3");
lruCache.put("key1","String4");//key已经存在原始putWithoutLock方法存在资源泄露
lruCache.put("key4","String5");
lruCache.clear();//ReentrantCache类clear()方法存在资源泄露
Assertions.assertEquals(5, removeCount.get());
}
}