diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotatedElementUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotatedElementUtil.java index 734c00c4c..3b4e9fcd9 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotatedElementUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotatedElementUtil.java @@ -15,8 +15,8 @@ package org.dromara.hutool.core.annotation; import org.dromara.hutool.core.annotation.elements.HierarchicalAnnotatedElements; import org.dromara.hutool.core.annotation.elements.MetaAnnotatedElement; import org.dromara.hutool.core.annotation.elements.RepeatableMetaAnnotatedElement; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; import org.dromara.hutool.core.array.ArrayUtil; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.util.ObjUtil; import java.lang.annotation.Annotation; @@ -133,7 +133,7 @@ import java.util.stream.Stream; *

缓存 *

为了避免注解以及{@link AnnotatedElement}层级结构解析过程中的大量反射调用, * 工具类为{@link AnnotatedElement}及其元注解信息进行了缓存。
- * 缓存功能默认基于{@link WeakKeyConcurrentMap}实现,会在gc时自动回收部分缓存数据。 + * 缓存功能默认基于{@link WeakConcurrentMap}实现,会在gc时自动回收部分缓存数据。 * 但是若有必要,也可以调用{@link #clearCaches()}方法主动清空缓存。 * * @author huangchengxing @@ -150,22 +150,22 @@ public class AnnotatedElementUtil { /** * 支持属性解析的{@link MetaAnnotatedElement}缓存 */ - private static final Map> RESOLVED_ELEMENT_CACHE = new WeakKeyConcurrentMap<>(); + private static final Map> RESOLVED_ELEMENT_CACHE = new WeakConcurrentMap<>(); /** * 不支持属性解析的{@link MetaAnnotatedElement}缓存 */ - private static final Map> ELEMENT_CACHE = new WeakKeyConcurrentMap<>(); + private static final Map> ELEMENT_CACHE = new WeakConcurrentMap<>(); /** * 不支持属性解析的{@link RepeatableMetaAnnotatedElement}缓存 */ - private static final Map> RESOLVED_REPEATABLE_ELEMENT_CACHE = new WeakKeyConcurrentMap<>(); + private static final Map> RESOLVED_REPEATABLE_ELEMENT_CACHE = new WeakConcurrentMap<>(); /** * 不支持属性解析的{@link RepeatableMetaAnnotatedElement}缓存 */ - private static final Map> REPEATABLE_ELEMENT_CACHE = new WeakKeyConcurrentMap<>(); + private static final Map> REPEATABLE_ELEMENT_CACHE = new WeakConcurrentMap<>(); // region ========== find ========== diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java index 855c10513..7d4c14bde 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java @@ -19,7 +19,7 @@ import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.func.LambdaInfo; import org.dromara.hutool.core.func.LambdaUtil; import org.dromara.hutool.core.func.SerFunction; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.reflect.FieldUtil; import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.text.CharSequenceUtil; @@ -50,7 +50,7 @@ public class AnnotationUtil { /** * 直接声明的注解缓存 */ - private static final Map DECLARED_ANNOTATIONS_CACHE = new WeakKeyConcurrentMap<>(); + private static final Map DECLARED_ANNOTATIONS_CACHE = new WeakConcurrentMap<>(); /** * 获取直接声明的注解,若已有缓存则从缓存中获取 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/RepeatableAnnotationCollector.java b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/RepeatableAnnotationCollector.java index fa5f5a7c7..5780c770c 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/RepeatableAnnotationCollector.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/RepeatableAnnotationCollector.java @@ -14,7 +14,7 @@ package org.dromara.hutool.core.annotation; import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.collection.CollUtil; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.text.CharSequenceUtil; @@ -337,7 +337,7 @@ public interface RepeatableAnnotationCollector { /** * 可重复注解对应的方法缓存 */ - private final Map, Object> repeatableMethodCache = new WeakKeyConcurrentMap<>(); + private final Map, Object> repeatableMethodCache = new WeakConcurrentMap<>(); /** * 构造 @@ -447,7 +447,7 @@ public interface RepeatableAnnotationCollector { /** * 可重复注解对应的方法缓存 */ - private final Map, Object> repeatableMethodCache = new WeakKeyConcurrentMap<>(); + private final Map, Object> repeatableMethodCache = new WeakConcurrentMap<>(); /** * 构造 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDescCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDescCache.java index 1563c0f9f..e026d873d 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDescCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanDescCache.java @@ -13,7 +13,7 @@ package org.dromara.hutool.core.bean; import org.dromara.hutool.core.func.SerSupplier; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; /** * Bean属性缓存
@@ -27,7 +27,7 @@ public enum BeanDescCache { */ INSTANCE; - private final WeakKeyConcurrentMap, BeanDesc> bdCache = new WeakKeyConcurrentMap<>(); + private final WeakConcurrentMap, BeanDesc> bdCache = new WeakConcurrentMap<>(); /** * 获得属性名和{@link BeanDesc}Map映射 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanInfoCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanInfoCache.java index 005f33e0b..e9e5a398a 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanInfoCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanInfoCache.java @@ -13,8 +13,8 @@ package org.dromara.hutool.core.bean; import org.dromara.hutool.core.func.SerSupplier; -import org.dromara.hutool.core.map.reference.ReferenceKeyConcurrentMap; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.ReferenceConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import java.beans.PropertyDescriptor; import java.util.Map; @@ -31,8 +31,8 @@ public enum BeanInfoCache { */ INSTANCE; - private final WeakKeyConcurrentMap, Map> pdCache = new WeakKeyConcurrentMap<>(); - private final WeakKeyConcurrentMap, Map> ignoreCasePdCache = new WeakKeyConcurrentMap<>(); + private final WeakConcurrentMap, Map> pdCache = new WeakConcurrentMap<>(); + private final WeakConcurrentMap, Map> ignoreCasePdCache = new WeakConcurrentMap<>(); /** * 获得属性名和{@link PropertyDescriptor}Map映射 @@ -86,10 +86,10 @@ public enum BeanInfoCache { * 根据是否忽略字段名的大小写,返回不用Cache对象 * * @param ignoreCase 是否忽略大小写 - * @return {@link ReferenceKeyConcurrentMap} + * @return {@link ReferenceConcurrentMap} * @since 5.4.1 */ - private ReferenceKeyConcurrentMap, Map> getCache(final boolean ignoreCase) { + private ReferenceConcurrentMap, Map> getCache(final boolean ignoreCase) { return ignoreCase ? ignoreCasePdCache : pdCache; } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/SimpleCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/SimpleCache.java index b48134b23..cc41d1b01 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/SimpleCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/SimpleCache.java @@ -18,7 +18,7 @@ import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.mutable.Mutable; import org.dromara.hutool.core.lang.mutable.MutableObj; import org.dromara.hutool.core.map.concurrent.SafeConcurrentHashMap; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import java.io.Serializable; import java.util.Iterator; @@ -33,7 +33,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; /** - * 简单缓存,无超时实现,默认使用{@link WeakKeyConcurrentMap}实现缓存自动清理 + * 简单缓存,无超时实现,默认使用{@link WeakConcurrentMap}实现缓存自动清理 * * @param 键类型 * @param 值类型 @@ -57,7 +57,7 @@ public class SimpleCache implements Iterable>, Serializabl * 构造,默认使用{@link WeakHashMap}实现缓存自动清理 */ public SimpleCache() { - this(new WeakKeyConcurrentMap<>()); + this(new WeakConcurrentMap<>()); } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java index e14a2f337..d8208fac4 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/WeakCache.java @@ -15,9 +15,8 @@ package org.dromara.hutool.core.cache.impl; import org.dromara.hutool.core.cache.CacheListener; import org.dromara.hutool.core.lang.Opt; import org.dromara.hutool.core.lang.mutable.Mutable; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; - -import java.lang.ref.Reference; +import org.dromara.hutool.core.lang.ref.Ref; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; /** * 弱引用缓存
@@ -39,16 +38,18 @@ public class WeakCache extends TimedCache{ * @param timeout 超时时常,单位毫秒,-1或0表示无限制 */ public WeakCache(final long timeout) { - super(timeout, new WeakKeyConcurrentMap<>()); + super(timeout, new WeakConcurrentMap<>()); } @Override public WeakCache setListener(final CacheListener listener) { super.setListener(listener); - final WeakKeyConcurrentMap, CacheObj> map = (WeakKeyConcurrentMap, CacheObj>) this.cacheMap; + 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())); + map.setPurgeListener((key, value)-> listener.onRemove( + Opt.ofNullable(key).map(Ref::get).map(Mutable::get).get(), + Opt.ofNullable(value).map(Ref::get).map(CacheObj::getValue).get())); return this; } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EnumConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EnumConverter.java index c12b55229..7a00d8975 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EnumConverter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EnumConverter.java @@ -16,10 +16,10 @@ import org.dromara.hutool.core.convert.AbstractConverter; import org.dromara.hutool.core.convert.ConvertException; import org.dromara.hutool.core.lang.EnumItem; import org.dromara.hutool.core.map.MapUtil; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.reflect.ClassUtil; -import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.reflect.ModifierUtil; +import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.util.EnumUtil; import java.lang.reflect.Method; @@ -42,7 +42,7 @@ public class EnumConverter extends AbstractConverter { */ public static final EnumConverter INSTANCE = new EnumConverter(); - private static final WeakKeyConcurrentMap, Map, Method>> VALUE_OF_METHOD_CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, Map, Method>> VALUE_OF_METHOD_CACHE = new WeakConcurrentMap<>(); @Override protected Object convertInternal(final Class targetClass, final Object value) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java b/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java index 4daa2d95d..0b3fb4120 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java @@ -15,8 +15,9 @@ package org.dromara.hutool.core.func; import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.mutable.MutableEntry; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; -import org.dromara.hutool.core.reflect.*; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; +import org.dromara.hutool.core.reflect.ClassUtil; +import org.dromara.hutool.core.reflect.ReflectUtil; import org.dromara.hutool.core.reflect.lookup.LookupUtil; import org.dromara.hutool.core.reflect.method.MethodTypeUtil; import org.dromara.hutool.core.reflect.method.MethodUtil; @@ -37,7 +38,7 @@ public class LambdaFactory { throw new IllegalAccessException(); } - private static final Map, Executable>, Object> CACHE = new WeakKeyConcurrentMap<>(); + private static final Map, Executable>, Object> CACHE = new WeakConcurrentMap<>(); /** * 构建Lambda diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaUtil.java index ead7b6429..3f0941350 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaUtil.java @@ -17,10 +17,10 @@ import org.dromara.hutool.core.classloader.ClassLoaderUtil; import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Opt; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.reflect.ClassDescUtil; -import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.reflect.ModifierUtil; +import org.dromara.hutool.core.reflect.method.MethodUtil; import java.io.Serializable; import java.lang.invoke.SerializedLambda; @@ -37,7 +37,7 @@ import java.util.function.*; */ public class LambdaUtil { - private static final WeakKeyConcurrentMap CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap CACHE = new WeakConcurrentMap<>(); /** * 通过对象的方法或类的静态方法引用,获取lambda实现类 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/intern/WeakIntern.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/intern/WeakIntern.java index 1f7611bde..8d8d7cb59 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/intern/WeakIntern.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/intern/WeakIntern.java @@ -12,7 +12,7 @@ package org.dromara.hutool.core.lang.intern; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import java.lang.ref.WeakReference; @@ -25,7 +25,7 @@ import java.lang.ref.WeakReference; */ public class WeakIntern implements Intern { - private final WeakKeyConcurrentMap> cache = new WeakKeyConcurrentMap<>(); + private final WeakConcurrentMap> cache = new WeakConcurrentMap<>(); @Override public T intern(final T sample) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/PhantomObj.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/PhantomObj.java new file mode 100644 index 000000000..500f57a71 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/PhantomObj.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.lang.ref; + +import org.dromara.hutool.core.util.ObjUtil; + +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; +import java.util.Objects; + +/** + * 虚引用对象,在GC时发现虚引用对象,会将{@link PhantomReference}插入{@link ReferenceQueue}。
+ * 此时对象未被真正回收,要等到{@link ReferenceQueue}被真正处理后才会被回收。 + * + * @param 键类型 + */ +public class PhantomObj extends PhantomReference implements Ref{ + private final int hashCode; + + /** + * 构造 + * + * @param obj 原始对象 + * @param queue {@link ReferenceQueue} + */ + public PhantomObj(final T obj, final ReferenceQueue queue) { + super(obj, queue); + hashCode = Objects.hashCode(obj); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public boolean equals(final Object other) { + if (other == this) { + return true; + } else if (other instanceof PhantomObj) { + return ObjUtil.equals(((PhantomObj) other).get(), get()); + } + return false; + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/Ref.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/Ref.java new file mode 100644 index 000000000..3f1e74e7f --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/Ref.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.lang.ref; + +/** + * 针对{@link java.lang.ref.Reference}的接口定义,用于扩展功能
+ * 例如提供自定义的无需回收对象 + * + * @param 对象类型 + */ +@FunctionalInterface +public interface Ref { + + /** + * 获取引用的原始对象 + * + * @return 原始对象 + */ + T get(); +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceType.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceType.java index be4a82e4b..e906b1b5d 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceType.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceType.java @@ -21,6 +21,10 @@ import java.lang.ref.ReferenceQueue; * @author looly */ public enum ReferenceType { + /** + * 强引用,不回收 + */ + STRONG, /** * 软引用,在GC报告内存不足时会被GC回收 */ diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceUtil.java index ef3f340b0..b54fd0c8f 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/ReferenceUtil.java @@ -79,4 +79,16 @@ public class ReferenceUtil { public static T get(final Reference obj) { return ObjUtil.apply(obj, Reference::get); } + + /** + * {@code null}全的解包获取原始对象 + * + * @param 对象类型 + * @param obj Ref对象 + * @return 原始对象 or {@code null} + * @since 6.0.0 + */ + public static T get(final Ref obj) { + return ObjUtil.apply(obj, Ref::get); + } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/SoftObj.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/SoftObj.java index ad665f0b8..96b37b3ef 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/SoftObj.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/SoftObj.java @@ -23,7 +23,7 @@ import java.util.Objects; * * @param 键类型 */ -public class SoftObj extends SoftReference { +public class SoftObj extends SoftReference implements Ref{ private final int hashCode; /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/StrongObj.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/StrongObj.java new file mode 100644 index 000000000..b6c8037e7 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/StrongObj.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.core.lang.ref; + +import org.dromara.hutool.core.util.ObjUtil; + +import java.util.Objects; + +/** + * 弱引用对象,在GC时发现弱引用会回收其对象 + * + * @param 键类型 + */ +public class StrongObj implements Ref { + + private final T obj; + + /** + * 构造 + * + * @param obj 原始对象 + */ + public StrongObj(final T obj) { + this.obj = obj; + } + + @Override + public T get() { + return this.obj; + } + + @Override + public int hashCode() { + return Objects.hashCode(obj); + } + + @Override + public boolean equals(final Object other) { + if (other == this) { + return true; + } else if (other instanceof StrongObj) { + return ObjUtil.equals(((StrongObj) other).get(), get()); + } + return false; + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/WeakObj.java b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/WeakObj.java index 89d09f9d1..f2a4ae56a 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/WeakObj.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/lang/ref/WeakObj.java @@ -23,7 +23,7 @@ import java.util.Objects; * * @param 键类型 */ -public class WeakObj extends WeakReference { +public class WeakObj extends WeakReference implements Ref{ private final int hashCode; /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/ReferenceConcurrentMap.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/ReferenceConcurrentMap.java index e189a0d69..32aae0301 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/ReferenceConcurrentMap.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/ReferenceConcurrentMap.java @@ -12,8 +12,9 @@ package org.dromara.hutool.core.map.reference; -import org.dromara.hutool.core.map.MapUtil; +import org.dromara.hutool.core.lang.ref.Ref; import org.dromara.hutool.core.lang.ref.ReferenceUtil; +import org.dromara.hutool.core.map.MapUtil; import java.io.Serializable; import java.lang.ref.Reference; @@ -34,13 +35,13 @@ import java.util.function.Function; public abstract class ReferenceConcurrentMap implements ConcurrentMap, Iterable>, Serializable { private static final long serialVersionUID = 1L; - final ConcurrentMap, Reference> raw; + final ConcurrentMap, Ref> raw; private final ReferenceQueue lastKeyQueue; private final ReferenceQueue lastValueQueue; /** * 回收监听 */ - private BiConsumer, Reference> purgeListener; + private BiConsumer, Ref> purgeListener; // region 构造 @@ -49,7 +50,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap, Reference> raw) { + public ReferenceConcurrentMap(final ConcurrentMap, Ref> raw) { this.raw = raw; lastKeyQueue = new ReferenceQueue<>(); lastValueQueue = new ReferenceQueue<>(); @@ -61,7 +62,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap, Reference> purgeListener) { + public void setPurgeListener(final BiConsumer, Ref> purgeListener) { this.purgeListener = purgeListener; } @@ -98,14 +99,14 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap vReference = this.raw.put(wrapKey(key), wrapValue(value)); + final Ref vReference = this.raw.put(wrapKey(key), wrapValue(value)); return unwrap(vReference); } @Override public V putIfAbsent(final K key, final V value) { this.purgeStale(); - final Reference vReference = this.raw.putIfAbsent(wrapKey(key), wrapValue(value)); + final Ref vReference = this.raw.putIfAbsent(wrapKey(key), wrapValue(value)); return unwrap(vReference); } @@ -117,7 +118,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap vReference = this.raw.replace(wrapKey(key), wrapValue(value)); + final Ref vReference = this.raw.replace(wrapKey(key), wrapValue(value)); return unwrap(vReference); } @@ -136,7 +137,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap mappingFunction) { this.purgeStale(); - final Reference vReference = this.raw.computeIfAbsent(wrapKey(key), + final Ref vReference = this.raw.computeIfAbsent(wrapKey(key), kReference -> wrapValue(mappingFunction.apply(unwrap(kReference)))); return unwrap(vReference); } @@ -144,7 +145,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap remappingFunction) { this.purgeStale(); - final Reference vReference = this.raw.computeIfPresent(wrapKey(key), + final Ref vReference = this.raw.computeIfPresent(wrapKey(key), (kReference, vReference1) -> wrapValue(remappingFunction.apply(unwrap(kReference), unwrap(vReference1)))); return unwrap(vReference); } @@ -173,11 +174,11 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap keySet() { this.purgeStale(); - final Set> referenceSet = this.raw.keySet(); + final Set> referenceSet = this.raw.keySet(); return new AbstractSet() { @Override public Iterator iterator() { - final Iterator> referenceIter = referenceSet.iterator(); + final Iterator> referenceIter = referenceSet.iterator(); return new Iterator() { @Override public boolean hasNext() { @@ -201,11 +202,11 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap values() { this.purgeStale(); - final Collection> referenceValues = this.raw.values(); + final Collection> referenceValues = this.raw.values(); return new AbstractCollection() { @Override public Iterator iterator() { - final Iterator> referenceIter = referenceValues.iterator(); + final Iterator> referenceIter = referenceValues.iterator(); return new Iterator() { @Override public boolean hasNext() { @@ -229,11 +230,11 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap> entrySet() { this.purgeStale(); - final Set, Reference>> referenceEntrySet = this.raw.entrySet(); + final Set, Ref>> referenceEntrySet = this.raw.entrySet(); return new AbstractSet>() { @Override public Iterator> iterator() { - final Iterator, Reference>> referenceIter = referenceEntrySet.iterator(); + final Iterator, Ref>> referenceIter = referenceEntrySet.iterator(); return new Iterator>() { @Override public boolean hasNext() { @@ -242,7 +243,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap next() { - final Entry, Reference> next = referenceIter.next(); + final Entry, Ref> next = referenceIter.next(); return new Entry() { @Override public K getKey() { @@ -300,11 +301,11 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap key; - Reference value; + Ref key; + Ref value; // 清除无效key对应键值对 - while ((key = this.lastKeyQueue.poll()) != null) { + while ((key = (Ref) this.lastKeyQueue.poll()) != null) { value = this.raw.remove(key); if (null != purgeListener) { purgeListener.accept(key, value); @@ -312,8 +313,8 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap) value); + while ((value = (Ref) this.lastValueQueue.poll()) != null) { + MapUtil.removeByValue(this.raw, (Ref) value); if (null != purgeListener) { purgeListener.accept(null, value); } @@ -327,7 +328,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap wrapKey(final K key, final ReferenceQueue queue); + abstract Ref wrapKey(final K key, final ReferenceQueue queue); /** * 根据Reference类型构建value对应的{@link Reference} @@ -336,7 +337,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap wrapValue(final V value, final ReferenceQueue queue); + abstract Ref wrapValue(final V value, final ReferenceQueue queue); /** * 根据Reference类型构建key对应的{@link Reference} @@ -345,7 +346,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap wrapKey(final Object key) { + private Ref wrapKey(final Object key) { return wrapKey((K) key, this.lastKeyQueue); } @@ -356,7 +357,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap wrapValue(final Object value) { + private Ref wrapValue(final Object value) { return wrapValue((V) value, this.lastValueQueue); } @@ -367,7 +368,7 @@ public abstract class ReferenceConcurrentMap implements ConcurrentMap T unwrap(final Reference obj) { + private static T unwrap(final Ref obj) { return ReferenceUtil.get(obj); } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/ReferenceKeyConcurrentMap.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/ReferenceKeyConcurrentMap.java deleted file mode 100644 index 3c53ca5d7..000000000 --- a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/ReferenceKeyConcurrentMap.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2023-2024. looly(loolly@aliyun.com) - * Hutool is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * https://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - -package org.dromara.hutool.core.map.reference; - -import org.dromara.hutool.core.collection.CollUtil; -import org.dromara.hutool.core.lang.ref.ReferenceType; -import org.dromara.hutool.core.lang.ref.SoftObj; -import org.dromara.hutool.core.lang.ref.WeakObj; - -import java.io.Serializable; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.util.*; -import java.util.concurrent.ConcurrentMap; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * 线程安全的ReferenceMap实现
- * 参考:jdk.management.resource.internal.WeakKeyConcurrentHashMap - * - * @param 键类型 - * @param 值类型 - * @author looly - */ -public class ReferenceKeyConcurrentMap implements ConcurrentMap, Iterable>, Serializable { - private static final long serialVersionUID = 1L; - - final ConcurrentMap, V> raw; - private final ReferenceQueue lastQueue; - private final ReferenceType keyType; - /** - * 回收监听 - */ - private BiConsumer, V> purgeListener; - - // region 构造 - - /** - * 构造 - * - * @param raw {@link ConcurrentMap}实现 - * @param referenceType Reference类型 - */ - public ReferenceKeyConcurrentMap(final ConcurrentMap, V> raw, final ReferenceType referenceType) { - this.raw = raw; - this.keyType = referenceType; - lastQueue = new ReferenceQueue<>(); - } - // endregion - - /** - * 设置对象回收清除监听 - * - * @param purgeListener 监听函数 - */ - public void setPurgeListener(final BiConsumer, V> purgeListener) { - this.purgeListener = purgeListener; - } - - @Override - public int size() { - this.purgeStaleKeys(); - return this.raw.size(); - } - - @Override - public boolean isEmpty() { - return 0 == size(); - } - - @SuppressWarnings("unchecked") - @Override - public V get(final Object key) { - this.purgeStaleKeys(); - return this.raw.get(ofKey((K) key, null)); - } - - @SuppressWarnings("unchecked") - @Override - public boolean containsKey(final Object key) { - this.purgeStaleKeys(); - return this.raw.containsKey(ofKey((K) key, null)); - } - - @Override - public boolean containsValue(final Object value) { - this.purgeStaleKeys(); - return this.raw.containsValue(value); - } - - @Override - public V put(final K key, final V value) { - this.purgeStaleKeys(); - return this.raw.put(ofKey(key, this.lastQueue), value); - } - - @Override - public V putIfAbsent(final K key, final V value) { - this.purgeStaleKeys(); - return this.raw.putIfAbsent(ofKey(key, this.lastQueue), value); - } - - @Override - public void putAll(final Map m) { - m.forEach(this::put); - } - - @Override - public V replace(final K key, final V value) { - this.purgeStaleKeys(); - return this.raw.replace(ofKey(key, this.lastQueue), value); - } - - @Override - public boolean replace(final K key, final V oldValue, final V newValue) { - this.purgeStaleKeys(); - return this.raw.replace(ofKey(key, this.lastQueue), oldValue, newValue); - } - - @Override - public void replaceAll(final BiFunction function) { - this.purgeStaleKeys(); - this.raw.replaceAll((kWeakKey, value) -> function.apply(kWeakKey.get(), value)); - } - - @Override - public V computeIfAbsent(final K key, final Function mappingFunction) { - this.purgeStaleKeys(); - return this.raw.computeIfAbsent(ofKey(key, this.lastQueue), kWeakKey -> mappingFunction.apply(key)); - } - - @Override - public V computeIfPresent(final K key, final BiFunction remappingFunction) { - this.purgeStaleKeys(); - return this.raw.computeIfPresent(ofKey(key, this.lastQueue), (kWeakKey, value) -> remappingFunction.apply(key, value)); - } - - @SuppressWarnings("unchecked") - @Override - public V remove(final Object key) { - this.purgeStaleKeys(); - return this.raw.remove(ofKey((K) key, null)); - } - - @SuppressWarnings("unchecked") - @Override - public boolean remove(final Object key, final Object value) { - this.purgeStaleKeys(); - return this.raw.remove(ofKey((K) key, null), value); - } - - @SuppressWarnings("StatementWithEmptyBody") - @Override - public void clear() { - this.raw.clear(); - while (lastQueue.poll() != null) ; - } - - @Override - public Set keySet() { - this.purgeStaleKeys(); - // TODO 非高效方式的set转换,应该返回一个view - final Collection trans = CollUtil.trans(this.raw.keySet(), (reference) -> null == reference ? null : reference.get()); - return new HashSet<>(trans); - } - - @Override - public Collection values() { - this.purgeStaleKeys(); - return this.raw.values(); - } - - @Override - public Set> entrySet() { - this.purgeStaleKeys(); - return this.raw.entrySet().stream() - .map(entry -> new AbstractMap.SimpleImmutableEntry<>(entry.getKey().get(), entry.getValue())) - .collect(Collectors.toSet()); - } - - @Override - public void forEach(final BiConsumer action) { - this.purgeStaleKeys(); - this.raw.forEach((key, value)-> action.accept(key.get(), value)); - } - - @Override - public Iterator> iterator() { - return entrySet().iterator(); - } - - @Override - public V compute(final K key, final BiFunction remappingFunction) { - this.purgeStaleKeys(); - return this.raw.compute(ofKey(key, this.lastQueue), (kWeakKey, value) -> remappingFunction.apply(key, value)); - } - - @Override - public V merge(final K key, final V value, final BiFunction remappingFunction) { - this.purgeStaleKeys(); - return this.raw.merge(ofKey(key, this.lastQueue), value, remappingFunction); - } - - /** - * 清除被回收的键 - */ - private void purgeStaleKeys() { - Reference reference; - V value; - while ((reference = this.lastQueue.poll()) != null) { - value = this.raw.remove(reference); - if (null != purgeListener) { - purgeListener.accept(reference, value); - } - } - } - - /** - * 根据Reference类型构建key对应的{@link Reference} - * - * @param key 键 - * @param queue {@link ReferenceQueue} - * @return {@link Reference} - */ - private Reference ofKey(final K key, final ReferenceQueue queue) { - switch (keyType) { - case WEAK: - return new WeakObj<>(key, queue); - case SOFT: - return new SoftObj<>(key, queue); - } - throw new IllegalArgumentException("Unsupported key type: " + keyType); - } -} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/SoftKeyConcurrentMap.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/SoftConcurrentMap.java similarity index 58% rename from hutool-core/src/main/java/org/dromara/hutool/core/map/reference/SoftKeyConcurrentMap.java rename to hutool-core/src/main/java/org/dromara/hutool/core/map/reference/SoftConcurrentMap.java index 7cc0ad1f9..d2ac39241 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/SoftKeyConcurrentMap.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/SoftConcurrentMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024. looly(loolly@aliyun.com) + * Copyright (c) 2024. looly(loolly@aliyun.com) * Hutool is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: @@ -12,27 +12,29 @@ package org.dromara.hutool.core.map.reference; -import org.dromara.hutool.core.lang.ref.ReferenceType; +import org.dromara.hutool.core.lang.ref.Ref; +import org.dromara.hutool.core.lang.ref.SoftObj; import org.dromara.hutool.core.map.concurrent.SafeConcurrentHashMap; -import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; import java.util.concurrent.ConcurrentMap; /** * 线程安全的SoftMap实现
+ * 键和值都为Soft引用,即,在GC报告内存不足时会被GC回收 * * @param 键类型 * @param 值类型 * @author looly * @since 6.0.0 */ -public class SoftKeyConcurrentMap extends ReferenceKeyConcurrentMap { +public class SoftConcurrentMap extends ReferenceConcurrentMap { private static final long serialVersionUID = 1L; /** * 构造 */ - public SoftKeyConcurrentMap() { + public SoftConcurrentMap() { this(new SafeConcurrentHashMap<>()); } @@ -41,7 +43,17 @@ public class SoftKeyConcurrentMap extends ReferenceKeyConcurrentMap * * @param raw {@link ConcurrentMap}实现 */ - public SoftKeyConcurrentMap(final ConcurrentMap, V> raw) { - super(raw, ReferenceType.SOFT); + public SoftConcurrentMap(final ConcurrentMap, Ref> raw) { + super(raw); + } + + @Override + Ref wrapKey(final K key, final ReferenceQueue queue) { + return new SoftObj<>(key, queue); + } + + @Override + Ref wrapValue(final V value, final ReferenceQueue queue) { + return new SoftObj<>(value, queue); } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/WeakKeyConcurrentMap.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/WeakConcurrentMap.java similarity index 57% rename from hutool-core/src/main/java/org/dromara/hutool/core/map/reference/WeakKeyConcurrentMap.java rename to hutool-core/src/main/java/org/dromara/hutool/core/map/reference/WeakConcurrentMap.java index d5be69e76..f0945e1a7 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/WeakKeyConcurrentMap.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/map/reference/WeakConcurrentMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024. looly(loolly@aliyun.com) + * Copyright (c) 2024. looly(loolly@aliyun.com) * Hutool is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: @@ -12,28 +12,29 @@ package org.dromara.hutool.core.map.reference; -import org.dromara.hutool.core.lang.ref.ReferenceType; +import org.dromara.hutool.core.lang.ref.Ref; +import org.dromara.hutool.core.lang.ref.WeakObj; import org.dromara.hutool.core.map.concurrent.SafeConcurrentHashMap; -import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; import java.util.concurrent.ConcurrentMap; /** * 线程安全的WeakMap实现
- * 参考:jdk.management.resource.internal.WeakKeyConcurrentHashMap + * 键和值都为Weak引用,即,在GC时发现弱引用会回收其对象 * * @param 键类型 * @param 值类型 * @author looly - * @since 5.8.0 + * @since 6.0.0 */ -public class WeakKeyConcurrentMap extends ReferenceKeyConcurrentMap { +public class WeakConcurrentMap extends ReferenceConcurrentMap { private static final long serialVersionUID = 1L; /** * 构造 */ - public WeakKeyConcurrentMap() { + public WeakConcurrentMap() { this(new SafeConcurrentHashMap<>()); } @@ -42,7 +43,17 @@ public class WeakKeyConcurrentMap extends ReferenceKeyConcurrentMap * * @param raw {@link ConcurrentMap}实现 */ - public WeakKeyConcurrentMap(final ConcurrentMap, V> raw) { - super(raw, ReferenceType.WEAK); + public WeakConcurrentMap(final ConcurrentMap, Ref> raw) { + super(raw); + } + + @Override + Ref wrapKey(final K key, final ReferenceQueue queue) { + return new WeakObj<>(key, queue); + } + + @Override + Ref wrapValue(final V value, final ReferenceQueue queue) { + return new WeakObj<>(value, queue); } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ActualTypeMapperPool.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ActualTypeMapperPool.java index 307bee0ee..603109fd0 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ActualTypeMapperPool.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ActualTypeMapperPool.java @@ -13,7 +13,7 @@ package org.dromara.hutool.core.reflect; import org.dromara.hutool.core.convert.Convert; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -29,7 +29,7 @@ import java.util.Map; */ public class ActualTypeMapperPool { - private static final WeakKeyConcurrentMap> CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap> CACHE = new WeakConcurrentMap<>(); /** * 获取泛型变量和泛型实际类型的对应关系Map diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ConstructorUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ConstructorUtil.java index 57e0ffd0e..212aa30fc 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ConstructorUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ConstructorUtil.java @@ -14,7 +14,7 @@ package org.dromara.hutool.core.reflect; import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.lang.Assert; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.reflect.creator.DefaultObjectCreator; import org.dromara.hutool.core.reflect.creator.PossibleObjectCreator; @@ -29,7 +29,7 @@ public class ConstructorUtil { /** * 构造对象缓存 */ - private static final WeakKeyConcurrentMap, Constructor[]> CONSTRUCTORS_CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, Constructor[]> CONSTRUCTORS_CACHE = new WeakConcurrentMap<>(); // --------------------------------------------------------------------------------------------------------- Constructor /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/FieldUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/FieldUtil.java index 3ca82868f..1ecf5febe 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/FieldUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/FieldUtil.java @@ -13,13 +13,13 @@ package org.dromara.hutool.core.reflect; import org.dromara.hutool.core.annotation.Alias; +import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.convert.Convert; import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.map.MapUtil; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.text.StrUtil; -import org.dromara.hutool.core.array.ArrayUtil; import java.lang.reflect.Field; import java.util.HashMap; @@ -36,7 +36,7 @@ public class FieldUtil { /** * 字段缓存 */ - private static final WeakKeyConcurrentMap, Field[]> FIELDS_CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, Field[]> FIELDS_CACHE = new WeakConcurrentMap<>(); // --------------------------------------------------------------------------------------------------------- Field diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodScanner.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodScanner.java index 8b7208936..75a3050dd 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodScanner.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodScanner.java @@ -16,7 +16,7 @@ import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.lang.mutable.Mutable; import org.dromara.hutool.core.lang.mutable.MutableObj; import org.dromara.hutool.core.map.MapUtil; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.reflect.ClassUtil; import java.lang.reflect.Method; @@ -63,7 +63,7 @@ import java.util.function.Predicate; *

缓存 *

对于{@link #getDeclaredMethods}与{@link #getMethods}方法与基于这两个方法实现的, * 所有{@code xxxFromMethods}与{@code xxxFromDeclaredMethods}方法, - * 都提供了缓存基于{@link WeakKeyConcurrentMap}的缓存支持。
+ * 都提供了缓存基于{@link WeakConcurrentMap}的缓存支持。
* {@link #getAllMethods}与所有{@code xxxFromAllMethods}方法都基于{@link #getDeclaredMethods}实现, * 但是每次全量查找,都需要重新遍历类层级结构,因此会带来一定的额外的性能损耗。
* 缓存在GC时会被回收,但是也可以通过{@link #clearCaches}手动清除缓存。 @@ -87,12 +87,12 @@ public class MethodScanner { /** * 方法缓存 */ - private static final WeakKeyConcurrentMap, Method[]> METHODS_CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, Method[]> METHODS_CACHE = new WeakConcurrentMap<>(); /** * 直接声明的方法缓存 */ - private static final WeakKeyConcurrentMap, Method[]> DECLARED_METHODS_CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, Method[]> DECLARED_METHODS_CACHE = new WeakConcurrentMap<>(); // region ============= basic ============= diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodUtil.java index 6b44de274..39039c05f 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodUtil.java @@ -22,7 +22,7 @@ import org.dromara.hutool.core.exception.ExceptionUtil; import org.dromara.hutool.core.exception.HutoolException; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Singleton; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.reflect.ClassUtil; import org.dromara.hutool.core.reflect.ConstructorUtil; import org.dromara.hutool.core.reflect.ModifierUtil; @@ -44,11 +44,11 @@ public class MethodUtil { /** * 方法缓存 */ - private static final WeakKeyConcurrentMap, Method[]> METHODS_CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, Method[]> METHODS_CACHE = new WeakConcurrentMap<>(); /** * 直接声明的方法缓存 */ - private static final WeakKeyConcurrentMap, Method[]> DECLARED_METHODS_CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, Method[]> DECLARED_METHODS_CACHE = new WeakConcurrentMap<>(); // --------------------------------------------------------------------------------------------------------- method diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/regex/PatternPool.java b/hutool-core/src/main/java/org/dromara/hutool/core/regex/PatternPool.java index 23976809c..0745613b8 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/regex/PatternPool.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/regex/PatternPool.java @@ -12,7 +12,7 @@ package org.dromara.hutool.core.regex; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import java.util.regex.Pattern; @@ -209,7 +209,7 @@ public class PatternPool { /** * Pattern池 */ - private static final WeakKeyConcurrentMap POOL = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap POOL = new WeakConcurrentMap<>(); /** * 先从Pattern池中查找正则对应的{@link Pattern},找不到则编译正则表达式并入池。 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrFormatter.java b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrFormatter.java index 2b9087b7d..e245d163b 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrFormatter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/text/placeholder/StrFormatter.java @@ -14,7 +14,7 @@ package org.dromara.hutool.core.text.placeholder; import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.lang.mutable.MutableEntry; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.placeholder.template.NamedPlaceholderStrTemplate; import org.dromara.hutool.core.text.placeholder.template.SinglePlaceholderStrTemplate; @@ -27,7 +27,7 @@ import java.util.Map; * @author Looly */ public class StrFormatter { - private static final WeakKeyConcurrentMap, StrTemplate> CACHE = new WeakKeyConcurrentMap<>(); + private static final WeakConcurrentMap, StrTemplate> CACHE = new WeakConcurrentMap<>(); /** * 格式化字符串
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/util/ObjUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/util/ObjUtil.java index 92fd2ef7f..bf8abcf7b 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/util/ObjUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/util/ObjUtil.java @@ -339,7 +339,7 @@ public class ObjUtil { * @return 映射函数的结果, 如果输入对象为 null,则返回 null */ public static R apply(final T source, final Function handler) { - return defaultIfNull(source, handler, null); + return defaultIfNull(source, handler, (R)null); } /** diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/map/WeakConcurrentMapTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/map/WeakConcurrentMapTest.java index cf98fed34..35860a42d 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/map/WeakConcurrentMapTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/map/WeakConcurrentMapTest.java @@ -12,7 +12,7 @@ package org.dromara.hutool.core.map; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.thread.ConcurrencyTester; import org.dromara.hutool.core.thread.ThreadUtil; import org.dromara.hutool.core.util.ObjUtil; @@ -23,10 +23,9 @@ import org.junit.jupiter.api.Test; public class WeakConcurrentMapTest { @Test - public void putAndGetTest(){ - final WeakKeyConcurrentMap map = new WeakKeyConcurrentMap<>(); - Object - key1 = new Object(); + public void putAndGetTest() { + final WeakConcurrentMap map = new WeakConcurrentMap<>(); + Object key1 = new Object(); final Object value1 = new Object(); Object key2 = new Object(); final Object value2 = new Object(); @@ -57,10 +56,10 @@ public class WeakConcurrentMapTest { } @Test - public void getConcurrencyTest(){ - final WeakKeyConcurrentMap cache = new WeakKeyConcurrentMap<>(); + public void getConcurrencyTest() { + final WeakConcurrentMap cache = new WeakConcurrentMap<>(); final ConcurrencyTester tester = new ConcurrencyTester(2000); - tester.test(()-> cache.computeIfAbsent("aaa" + RandomUtil.randomInt(2), (key)-> "aaaValue")); + tester.test(() -> cache.computeIfAbsent("aaa" + RandomUtil.randomInt(2), (key) -> "aaaValue")); Assertions.assertTrue(tester.getInterval() > 0); final String value = ObjUtil.defaultIfNull(cache.get("aaa0"), cache.get("aaa1")); diff --git a/hutool-extra/src/main/java/org/dromara/hutool/extra/spring/cglib/BeanCopierCache.java b/hutool-extra/src/main/java/org/dromara/hutool/extra/spring/cglib/BeanCopierCache.java index 62dcd5648..3e991029a 100644 --- a/hutool-extra/src/main/java/org/dromara/hutool/extra/spring/cglib/BeanCopierCache.java +++ b/hutool-extra/src/main/java/org/dromara/hutool/extra/spring/cglib/BeanCopierCache.java @@ -12,7 +12,7 @@ package org.dromara.hutool.extra.spring.cglib; -import org.dromara.hutool.core.map.reference.WeakKeyConcurrentMap; +import org.dromara.hutool.core.map.reference.WeakConcurrentMap; import org.dromara.hutool.core.text.StrUtil; import org.springframework.cglib.beans.BeanCopier; import org.springframework.cglib.core.Converter; @@ -30,7 +30,7 @@ public enum BeanCopierCache { */ INSTANCE; - private final WeakKeyConcurrentMap cache = new WeakKeyConcurrentMap<>(); + private final WeakConcurrentMap cache = new WeakConcurrentMap<>(); /** * 获得类与转换器生成的key在{@link BeanCopier}的Map中对应的元素