This commit is contained in:
Looly 2022-05-27 20:13:20 +08:00
parent 705f65a207
commit e1437f9b65
7 changed files with 15 additions and 18 deletions

View File

@ -52,7 +52,16 @@ public final class Singleton {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T get(final String key, final Func0<T> supplier) { public static <T> T get(final String key, final Func0<T> 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;
} }
/** /**

View File

@ -1,7 +1,6 @@
package cn.hutool.core.map; package cn.hutool.core.map;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ReferenceUtil; import cn.hutool.core.util.ReferenceUtil;
@ -143,17 +142,6 @@ public class ReferenceConcurrentMap<K, V> implements ConcurrentMap<K, V>, Iterab
return this.raw.computeIfPresent(ofKey(key, this.lastQueue), (kWeakKey, value) -> remappingFunction.apply(key, value)); 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<? extends V> supplier) {
return computeIfAbsent(key, (keyParam) -> supplier.callWithRuntimeException());
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public V remove(final Object key) { public V remove(final Object key) {

View File

@ -64,7 +64,7 @@ public class ConstructorUtil {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> Constructor<T>[] getConstructors(final Class<T> beanClass) throws SecurityException { public static <T> Constructor<T>[] getConstructors(final Class<T> beanClass) throws SecurityException {
Assert.notNull(beanClass); Assert.notNull(beanClass);
return (Constructor<T>[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, () -> getConstructorsDirectly(beanClass)); return (Constructor<T>[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, (key) -> getConstructorsDirectly(beanClass));
} }
/** /**

View File

@ -116,7 +116,7 @@ public class FieldUtil {
*/ */
public static Field[] getFields(final Class<?> beanClass) throws SecurityException { public static Field[] getFields(final Class<?> beanClass) throws SecurityException {
Assert.notNull(beanClass); Assert.notNull(beanClass);
return FIELDS_CACHE.computeIfAbsent(beanClass, () -> getFieldsDirectly(beanClass, true)); return FIELDS_CACHE.computeIfAbsent(beanClass, (key) -> getFieldsDirectly(beanClass, true));
} }

View File

@ -320,7 +320,7 @@ public class MethodUtil {
public static Method[] getMethods(final Class<?> beanClass) throws SecurityException { public static Method[] getMethods(final Class<?> beanClass) throws SecurityException {
Assert.notNull(beanClass); Assert.notNull(beanClass);
return METHODS_CACHE.computeIfAbsent(beanClass, return METHODS_CACHE.computeIfAbsent(beanClass,
() -> getMethodsDirectly(beanClass, true, true)); (key) -> getMethodsDirectly(beanClass, true, true));
} }
/** /**

View File

@ -30,7 +30,7 @@ public class ScriptUtil {
* @return {@link ScriptEngine} 实例 * @return {@link ScriptEngine} 实例
*/ */
public static ScriptEngine getScript(final String nameOrExtOrMime) { public static ScriptEngine getScript(final String nameOrExtOrMime) {
return CACHE.computeIfAbsent(nameOrExtOrMime, () -> createScript(nameOrExtOrMime)); return CACHE.computeIfAbsent(nameOrExtOrMime, (key) -> createScript(nameOrExtOrMime));
} }
/** /**

View File

@ -43,7 +43,7 @@ public enum BeanCopierCache {
*/ */
public BeanCopier get(final Class<?> srcClass, final Class<?> targetClass, final boolean useConverter) { public BeanCopier get(final Class<?> srcClass, final Class<?> targetClass, final boolean useConverter) {
final String key = genKey(srcClass, targetClass, 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));
} }
/** /**