diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java b/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java index 18e457896..7bb68d7ac 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java @@ -52,7 +52,16 @@ public final class Singleton { */ @SuppressWarnings("unchecked") public static T get(final String key, final Func0 supplier) { - return (T) POOL.computeIfAbsent(key, (k)-> supplier.callWithRuntimeException()); + //return (T) POOL.computeIfAbsent(key, (k)-> supplier.callWithRuntimeException()); + // issues#2349 + // ConcurrentHashMap.computeIfAbsent在某些情况下会导致死循环问题,此处采用Dubbo的解决方案 + + Object value = POOL.get(key); + if(null == value){ + POOL.putIfAbsent(key, supplier.callWithRuntimeException()); + value = POOL.get(key); + } + return (T) value; } /** 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 24aa640b5..6e7d43212 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 @@ -1,7 +1,6 @@ package cn.hutool.core.map; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.func.Func0; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ReferenceUtil; @@ -143,17 +142,6 @@ public class ReferenceConcurrentMap implements ConcurrentMap, Iterab return this.raw.computeIfPresent(ofKey(key, this.lastQueue), (kWeakKey, value) -> remappingFunction.apply(key, value)); } - /** - * 从缓存中获得对象,当对象不在缓存中或已经过期返回Func0回调产生的对象 - * - * @param key 键 - * @param supplier 如果不存在回调方法,用于生产值对象 - * @return 值对象 - */ - public V computeIfAbsent(final K key, final Func0 supplier) { - return computeIfAbsent(key, (keyParam) -> supplier.callWithRuntimeException()); - } - @SuppressWarnings("unchecked") @Override public V remove(final Object key) { diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/ConstructorUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/ConstructorUtil.java index f36b8bcf5..6c45826b1 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/ConstructorUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/ConstructorUtil.java @@ -64,7 +64,7 @@ public class ConstructorUtil { @SuppressWarnings("unchecked") public static Constructor[] getConstructors(final Class beanClass) throws SecurityException { Assert.notNull(beanClass); - return (Constructor[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, () -> getConstructorsDirectly(beanClass)); + return (Constructor[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, (key) -> getConstructorsDirectly(beanClass)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/FieldUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/FieldUtil.java index 3229d4e53..172cdcf0b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/FieldUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/FieldUtil.java @@ -116,7 +116,7 @@ public class FieldUtil { */ public static Field[] getFields(final Class beanClass) throws SecurityException { Assert.notNull(beanClass); - return FIELDS_CACHE.computeIfAbsent(beanClass, () -> getFieldsDirectly(beanClass, true)); + return FIELDS_CACHE.computeIfAbsent(beanClass, (key) -> getFieldsDirectly(beanClass, true)); } diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java index ee769dab6..0eaf74075 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java @@ -320,7 +320,7 @@ public class MethodUtil { public static Method[] getMethods(final Class beanClass) throws SecurityException { Assert.notNull(beanClass); return METHODS_CACHE.computeIfAbsent(beanClass, - () -> getMethodsDirectly(beanClass, true, true)); + (key) -> getMethodsDirectly(beanClass, true, true)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ScriptUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ScriptUtil.java index c68f6f02c..3b567aa65 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/ScriptUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ScriptUtil.java @@ -30,7 +30,7 @@ public class ScriptUtil { * @return {@link ScriptEngine} 实例 */ public static ScriptEngine getScript(final String nameOrExtOrMime) { - return CACHE.computeIfAbsent(nameOrExtOrMime, () -> createScript(nameOrExtOrMime)); + return CACHE.computeIfAbsent(nameOrExtOrMime, (key) -> createScript(nameOrExtOrMime)); } /** diff --git a/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java b/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java index 4d882a98d..ff54db04c 100755 --- a/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/cglib/BeanCopierCache.java @@ -43,7 +43,7 @@ public enum BeanCopierCache { */ public BeanCopier get(final Class srcClass, final Class targetClass, final boolean useConverter) { final String key = genKey(srcClass, targetClass, useConverter); - return cache.computeIfAbsent(key, () -> BeanCopier.create(srcClass, targetClass, useConverter)); + return cache.computeIfAbsent(key, (k) -> BeanCopier.create(srcClass, targetClass, useConverter)); } /**