mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
修复ConcurrentHashMap.computeIfAbsent缺陷导致的问题
This commit is contained in:
parent
3fd1ebe0f5
commit
920fe44e50
@ -18,6 +18,7 @@
|
||||
* 【db 】 修复Hive2驱动无法识别问题(issue#2606@Github)
|
||||
* 【core 】 修复computeIfAbsent问题(issue#I5PTN3@Gitee)
|
||||
* 【extra 】 修复Ftp中路径问题(issue#I5R2DE@Gitee)
|
||||
* 【core 】 修复ConcurrentHashMap.computeIfAbsent缺陷导致的问题
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.core.bean;
|
||||
|
||||
import cn.hutool.core.lang.func.Func0;
|
||||
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(Class<?> beanClass, Func0<BeanDesc> supplier) {
|
||||
return bdCache.computeIfAbsent(beanClass, (key)->supplier.callWithRuntimeException());
|
||||
return MapUtil.computeIfAbsent(bdCache, beanClass, (key)->supplier.callWithRuntimeException());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.lang.func.Func0;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
@ -52,15 +53,7 @@ public final class Singleton {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T get(String key, Func0<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.callWithRuntimeException());
|
||||
value = POOL.get(key);
|
||||
}
|
||||
return (T) value;
|
||||
return (T) MapUtil.computeIfAbsent(POOL, key, (k)-> supplier.callWithRuntimeException());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1464,17 +1464,19 @@ public class MapUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法来自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(Map<K, V> map, K key, 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;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.JarClassLoader;
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.map.WeakConcurrentMap;
|
||||
import cn.hutool.core.text.CharPool;
|
||||
|
||||
@ -50,7 +51,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<Pair<String, ClassLoader>, Class<?>> CLASS_CACHE = new WeakConcurrentMap<>();
|
||||
private static final Map<Pair<String, ClassLoader>, Class<?>> CLASS_CACHE = new WeakConcurrentMap<>();
|
||||
|
||||
static {
|
||||
List<Class<?>> primitiveTypes = new ArrayList<>(32);
|
||||
@ -199,7 +200,7 @@ public class ClassLoaderUtil {
|
||||
if (clazz == null) {
|
||||
final String finalName = name;
|
||||
final ClassLoader finalClassLoader = classLoader;
|
||||
clazz = CLASS_CACHE.computeIfAbsent(Pair.of(name, classLoader), (key)-> doLoadClass(finalName, finalClassLoader, isInitialized));
|
||||
clazz = MapUtil.computeIfAbsent(CLASS_CACHE, Pair.of(name, classLoader), (key)-> doLoadClass(finalName, finalClassLoader, isInitialized));
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user