diff --git a/hutool-cache/src/main/java/cn/hutool/cache/impl/WeakCache.java b/hutool-cache/src/main/java/cn/hutool/cache/impl/WeakCache.java
index 4d32b7ed6..a6fb23690 100644
--- a/hutool-cache/src/main/java/cn/hutool/cache/impl/WeakCache.java
+++ b/hutool-cache/src/main/java/cn/hutool/cache/impl/WeakCache.java
@@ -1,7 +1,12 @@
package cn.hutool.cache.impl;
+import cn.hutool.cache.CacheListener;
+import cn.hutool.core.lang.Opt;
+import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.map.WeakConcurrentMap;
+import java.lang.ref.Reference;
+
/**
* 弱引用缓存
* 对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。
@@ -24,4 +29,15 @@ public class WeakCache extends TimedCache{
public WeakCache(long timeout) {
super(timeout, new WeakConcurrentMap<>());
}
+
+ @Override
+ public WeakCache setListener(CacheListener listener) {
+ super.setListener(listener);
+
+ final WeakConcurrentMap, CacheObj> map = (WeakConcurrentMap, CacheObj>) this.cacheMap;
+ // WeakKey回收之后,key对应的值已经是null了,因此此处的key也为null
+ map.setPurgeListener((key, value)-> listener.onRemove(Opt.ofNullable(key).map(Reference::get).map(Mutable::get).get(), value.getValue()));
+
+ return this;
+ }
}
diff --git a/hutool-cache/src/test/java/cn/hutool/cache/WeakCacheTest.java b/hutool-cache/src/test/java/cn/hutool/cache/WeakCacheTest.java
index cdf0404b3..f61ed77b7 100644
--- a/hutool-cache/src/test/java/cn/hutool/cache/WeakCacheTest.java
+++ b/hutool-cache/src/test/java/cn/hutool/cache/WeakCacheTest.java
@@ -26,11 +26,13 @@ public class WeakCacheTest {
@Ignore
public void removeByGcTest(){
// https://gitee.com/dromara/hutool/issues/I51O7M
- // 经过GC,
WeakCache cache = new WeakCache<>(-1);
cache.put("a", "1");
cache.put("b", "2");
+
+ // 监听
Assert.assertEquals(2, cache.size());
+ cache.setListener(Console::log);
// GC测试
int i=0;
diff --git a/hutool-core/src/main/java/cn/hutool/core/map/ReferenceConcurrentMap.java b/hutool-core/src/main/java/cn/hutool/core/map/ReferenceConcurrentMap.java
index a976ca30f..99e80a877 100755
--- a/hutool-core/src/main/java/cn/hutool/core/map/ReferenceConcurrentMap.java
+++ b/hutool-core/src/main/java/cn/hutool/core/map/ReferenceConcurrentMap.java
@@ -2,7 +2,6 @@ package cn.hutool.core.map;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func0;
-import cn.hutool.core.lang.func.VoidFunc1;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReferenceUtil;
@@ -40,7 +39,7 @@ public class ReferenceConcurrentMap implements ConcurrentMap, Iterab
/**
* 回收监听
*/
- private VoidFunc1> purgeListener;
+ private BiConsumer, V> purgeListener;
// region 构造
@@ -62,7 +61,7 @@ public class ReferenceConcurrentMap implements ConcurrentMap, Iterab
*
* @param purgeListener 监听函数
*/
- public void setPurgeListener(VoidFunc1> purgeListener) {
+ public void setPurgeListener(BiConsumer, V> purgeListener) {
this.purgeListener = purgeListener;
}
@@ -225,10 +224,11 @@ public class ReferenceConcurrentMap implements ConcurrentMap, Iterab
*/
private void purgeStaleKeys() {
Reference extends K> reference;
+ V value;
while ((reference = this.lastQueue.poll()) != null) {
- this.raw.remove(reference);
+ value = this.raw.remove(reference);
if (null != purgeListener) {
- purgeListener.callWithRuntimeException(reference);
+ purgeListener.accept(reference, value);
}
}
}