From c57ecead276ef2b9684a3a37b0cd235c3382082c Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 17 Apr 2022 17:56:53 +0800 Subject: [PATCH] fix code --- .../java/cn/hutool/cache/impl/WeakCache.java | 16 ++++++++++++++++ .../test/java/cn/hutool/cache/WeakCacheTest.java | 4 +++- .../hutool/core/map/ReferenceConcurrentMap.java | 10 +++++----- 3 files changed, 24 insertions(+), 6 deletions(-) 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 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); } } }