This commit is contained in:
Looly 2022-09-15 01:53:47 +08:00
parent 7d091ae95a
commit 23d90a8896
16 changed files with 36 additions and 33 deletions

View File

@ -1,5 +1,6 @@
package cn.hutool.core.annotation;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
@ -16,7 +17,7 @@ import java.util.stream.Stream;
* 并提供诸如基于{@link Alias}的属性别名基于父子注解间的属性值覆盖等特殊的属性映射机制支持
*
* <p><strong>搜索层级结构</strong>
* <p>参考 Spring <code>AnnotatedElementUtils</code>
* <p>参考 Spring {@code AnnotatedElementUtils}
* 工具类提供<em>get</em>以及<em>find</em>两种语义的搜索
* <ul>
* <li><em>get</em>表示搜索范围仅限于指定的{@link AnnotatedElement}本身</li>
@ -494,7 +495,7 @@ public class AnnotatedElementUtil {
* @return {@link MetaAnnotatedElement}实例
*/
private static MetaAnnotatedElement<ResolvedAnnotationMapping> getResolvedMetaElementCache(final AnnotatedElement element) {
return RESOLVED_ELEMENT_CACHE.computeIfAbsent(element, ele -> MetaAnnotatedElement.create(
return MapUtil.computeIfAbsent(RESOLVED_ELEMENT_CACHE, element, ele -> MetaAnnotatedElement.create(
element, (source, annotation) -> ResolvedAnnotationMapping.create(source, annotation, true)
));
}
@ -506,7 +507,7 @@ public class AnnotatedElementUtil {
* @return {@link MetaAnnotatedElement}实例
*/
private static MetaAnnotatedElement<GenericAnnotationMapping> getMetaElementCache(final AnnotatedElement element) {
return ELEMENT_CACHE.computeIfAbsent(element, ele -> MetaAnnotatedElement.create(
return MapUtil.computeIfAbsent(ELEMENT_CACHE, element, ele -> MetaAnnotatedElement.create(
element, (source, annotation) -> GenericAnnotationMapping.create(annotation, Objects.isNull(source))
));
}

View File

@ -1,6 +1,7 @@
package cn.hutool.core.bean;
import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
/**
@ -23,7 +24,7 @@ public enum BeanDescCache {
* @since 5.4.2
*/
public BeanDesc getBeanDesc(final Class<?> beanClass, final SerSupplier<BeanDesc> supplier) {
return bdCache.computeIfAbsent(beanClass, (key) -> supplier.get());
return MapUtil.computeIfAbsent(bdCache, beanClass, (key) -> supplier.get());
}
/**

View File

@ -50,7 +50,7 @@ public class ClassLoaderUtil {
* 原始类型名和其class对应表例如int = int.class
*/
private static final Map<String, Class<?>> PRIMITIVE_TYPE_NAME_MAP = new ConcurrentHashMap<>(32);
private static final WeakConcurrentMap<Map.Entry<String, ClassLoader>, Class<?>> CLASS_CACHE = new WeakConcurrentMap<>();
private static final Map<Map.Entry<String, ClassLoader>, Class<?>> CLASS_CACHE = new WeakConcurrentMap<>();
static {
final List<Class<?>> primitiveTypes = new ArrayList<>(32);
@ -203,7 +203,7 @@ public class ClassLoaderUtil {
if (clazz == null) {
final String finalName = name;
final ClassLoader finalClassLoader = classLoader;
clazz = CLASS_CACHE.computeIfAbsent(MapUtil.entry(name, classLoader), (key) -> doLoadClass(finalName, finalClassLoader, isInitialized));
clazz = MapUtil.computeIfAbsent(CLASS_CACHE, MapUtil.entry(name, classLoader), (key) -> doLoadClass(finalName, finalClassLoader, isInitialized));
}
return (Class<T>) clazz;
}

View File

@ -118,7 +118,7 @@ public class EnumConverter extends AbstractConverter {
* @return 转换方法mapkey为方法参数类型value为方法
*/
private static Map<Class<?>, Method> getMethodMap(final Class<?> enumClass) {
return VALUE_OF_METHOD_CACHE.computeIfAbsent(enumClass, (key) -> Arrays.stream(enumClass.getMethods())
return MapUtil.computeIfAbsent(VALUE_OF_METHOD_CACHE, enumClass, (key) -> Arrays.stream(enumClass.getMethods())
.filter(ModifierUtil::isStatic)
.filter(m -> m.getReturnType() == enumClass)
.filter(m -> m.getParameterCount() == 1)

View File

@ -2,6 +2,7 @@ package cn.hutool.core.lang;
import cn.hutool.core.classloader.ClassLoaderUtil;
import cn.hutool.core.lang.func.SerSupplier;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.reflect.ConstructorUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil;
@ -52,16 +53,7 @@ public final class Singleton {
*/
@SuppressWarnings("unchecked")
public static <T> T get(final String key, final SerSupplier<T> supplier) {
//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.get());
value = POOL.get(key);
}
return (T) value;
return (T) MapUtil.computeIfAbsent(POOL, key, (k)-> supplier.get());
}
/**

View File

@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.classloader.ClassLoaderUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.reflect.MethodUtil;
import cn.hutool.core.reflect.ReflectUtil;
@ -73,7 +74,7 @@ public class LambdaUtil {
* @return 返回解析后的结果
*/
public static <T extends Serializable> LambdaInfo resolve(final T func) {
return CACHE.computeIfAbsent(func.getClass().getName(), (key) -> {
return MapUtil.computeIfAbsent(CACHE, func.getClass().getName(), (key) -> {
final SerializedLambda serializedLambda = _resolve(func);
final String methodName = serializedLambda.getImplMethodName();
final Class<?> implClass;

View File

@ -1,5 +1,6 @@
package cn.hutool.core.lang.intern;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
/**
@ -17,6 +18,6 @@ public class WeakInterner<T> implements Interner<T>{
if(null == sample){
return null;
}
return cache.computeIfAbsent(sample, (key)->sample);
return MapUtil.computeIfAbsent(cache, sample, (key)->sample);
}
}

View File

@ -1265,17 +1265,19 @@ public class MapUtil extends MapGetUtil {
}
/**
* 方法来自MyBatis解决使用ConcurrentHashMap.computeIfAbsent导致的死循环问题<br>
* 方法来自Dubbo解决使用ConcurrentHashMap.computeIfAbsent导致的死循环问题<br>
* issues#2349<br>
* A temporary workaround for Java 8 specific performance issue JDK-8161372 .<br>
* This class should be removed once we drop Java 8 support.
*
* @see <a href="https://bugs.openjdk.java.net/browse/JDK-8161372">https://bugs.openjdk.java.net/browse/JDK-8161372</a>
*/
public static <K, V> V computeIfAbsent(final Map<K, V> map, final K key, final Function<K, V> mappingFunction) {
final V value = map.get(key);
if (value != null) {
return value;
V value = map.get(key);
if(null == value){
map.putIfAbsent(key, mappingFunction.apply(key));
value = map.get(key);
}
return map.computeIfAbsent(key, mappingFunction);
return value;
}
}

View File

@ -1,6 +1,7 @@
package cn.hutool.core.reflect;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import java.lang.reflect.ParameterizedType;
@ -26,7 +27,7 @@ public class ActualTypeMapperPool {
* @return 泛型对应关系Map
*/
public static Map<Type, Type> get(final Type type) {
return CACHE.computeIfAbsent(type, (key) -> createTypeMap(type));
return MapUtil.computeIfAbsent(CACHE, type, (key) -> createTypeMap(type));
}
/**

View File

@ -2,6 +2,7 @@ package cn.hutool.core.reflect;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.util.ArrayUtil;
@ -64,7 +65,7 @@ public class ConstructorUtil {
@SuppressWarnings("unchecked")
public static <T> Constructor<T>[] getConstructors(final Class<T> beanClass) throws SecurityException {
Assert.notNull(beanClass);
return (Constructor<T>[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, (key) -> getConstructorsDirectly(beanClass));
return (Constructor<T>[]) MapUtil.computeIfAbsent(CONSTRUCTORS_CACHE, beanClass, (key) -> getConstructorsDirectly(beanClass));
}
/**

View File

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

View File

@ -9,6 +9,7 @@ import cn.hutool.core.exceptions.InvocationTargetRuntimeException;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Singleton;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ArrayUtil;
@ -319,7 +320,7 @@ public class MethodUtil {
*/
public static Method[] getMethods(final Class<?> beanClass) throws SecurityException {
Assert.notNull(beanClass);
return METHODS_CACHE.computeIfAbsent(beanClass,
return MapUtil.computeIfAbsent(METHODS_CACHE, beanClass,
(key) -> getMethodsDirectly(beanClass, true, true));
}

View File

@ -1,5 +1,6 @@
package cn.hutool.core.regex;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import java.util.regex.Pattern;
@ -197,7 +198,7 @@ public class PatternPool {
*/
public static Pattern get(final String regex, final int flags) {
final RegexWithFlag regexWithFlag = new RegexWithFlag(regex, flags);
return POOL.computeIfAbsent(regexWithFlag, (key) -> Pattern.compile(regex, flags));
return MapUtil.computeIfAbsent(POOL, regexWithFlag, (key) -> Pattern.compile(regex, flags));
}
/**

View File

@ -27,7 +27,7 @@ public class LambdaUtilTest {
}
@Test
public <T> void resolveTest() {
public void resolveTest() {
Stream.<Runnable>of(() -> {
// 引用构造函数
final SerSupplier<MyTeacher> lambda = MyTeacher::new;
@ -116,7 +116,6 @@ public class LambdaUtilTest {
Assert.assertEquals(Enum.class, LambdaUtil.getRealClass(lambda));
}, () -> {
// 调用父类方法只能获取到父类类型
//noinspection ResultOfMethodCallIgnored
final SerSupplier<?> lambda = myTeacher::getId;
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
}, () -> {

View File

@ -1,5 +1,6 @@
package cn.hutool.extra.cglib;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.text.StrUtil;
import net.sf.cglib.beans.BeanCopier;
@ -43,7 +44,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, (k) -> BeanCopier.create(srcClass, targetClass, useConverter));
return MapUtil.computeIfAbsent(cache, key, (k) -> BeanCopier.create(srcClass, targetClass, useConverter));
}
/**

View File

@ -1,6 +1,7 @@
package cn.hutool.extra.script;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.map.WeakConcurrentMap;
import cn.hutool.core.text.StrUtil;
@ -30,7 +31,7 @@ public class ScriptUtil {
* @return {@link ScriptEngine} 实例
*/
public static ScriptEngine getScript(final String nameOrExtOrMime) {
return CACHE.computeIfAbsent(nameOrExtOrMime, (key) -> createScript(nameOrExtOrMime));
return MapUtil.computeIfAbsent(CACHE, nameOrExtOrMime, (key) -> createScript(nameOrExtOrMime));
}
/**