diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java index 06c80409f..2407de316 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java @@ -1,6 +1,5 @@ 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; @@ -495,7 +494,7 @@ public class AnnotatedElementUtil { * @return {@link MetaAnnotatedElement}实例 */ private static MetaAnnotatedElement getResolvedMetaElementCache(final AnnotatedElement element) { - return MapUtil.computeIfAbsent(RESOLVED_ELEMENT_CACHE, element, ele -> MetaAnnotatedElement.create( + return RESOLVED_ELEMENT_CACHE.computeIfAbsent(element, ele -> MetaAnnotatedElement.create( element, (source, annotation) -> ResolvedAnnotationMapping.create(source, annotation, true) )); } @@ -507,7 +506,7 @@ public class AnnotatedElementUtil { * @return {@link MetaAnnotatedElement}实例 */ private static MetaAnnotatedElement getMetaElementCache(final AnnotatedElement element) { - return MapUtil.computeIfAbsent(ELEMENT_CACHE, element, ele -> MetaAnnotatedElement.create( + return ELEMENT_CACHE.computeIfAbsent(element, ele -> MetaAnnotatedElement.create( element, (source, annotation) -> GenericAnnotationMapping.create(annotation, Objects.isNull(source)) )); } diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationMappingProxy.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationMappingProxy.java index 59dd3ea0d..a1ddc7d46 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationMappingProxy.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationMappingProxy.java @@ -1,5 +1,6 @@ package cn.hutool.core.annotation; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.reflect.MethodUtil; import cn.hutool.core.text.CharSequenceUtil; @@ -11,7 +12,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -80,7 +80,7 @@ public final class AnnotationMappingProxy implements Invoc private AnnotationMappingProxy(final AnnotationMapping annotation) { int methodCount = annotation.getAttributes().length; this.methods = new HashMap<>(methodCount + 5); - this.valueCache = new ConcurrentHashMap<>(methodCount); + this.valueCache = new SafeConcurrentHashMap<>(methodCount); this.mapping = annotation; loadMethods(); } diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java index f9ec5e2e8..b9b7739b3 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDescCache.java @@ -1,7 +1,6 @@ package cn.hutool.core.bean; import cn.hutool.core.lang.func.SerSupplier; -import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.WeakConcurrentMap; /** @@ -24,7 +23,7 @@ public enum BeanDescCache { * @since 5.4.2 */ public BeanDesc getBeanDesc(final Class beanClass, final SerSupplier supplier) { - return MapUtil.computeIfAbsent(bdCache, beanClass, (key) -> supplier.get()); + return bdCache.computeIfAbsent(beanClass, (key) -> supplier.get()); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/cache/SimpleCache.java b/hutool-core/src/main/java/cn/hutool/core/cache/SimpleCache.java index adad6683a..572317caf 100644 --- a/hutool-core/src/main/java/cn/hutool/core/cache/SimpleCache.java +++ b/hutool-core/src/main/java/cn/hutool/core/cache/SimpleCache.java @@ -4,14 +4,13 @@ import cn.hutool.core.collection.iter.TransIter; import cn.hutool.core.lang.func.SerSupplier; import cn.hutool.core.lang.mutable.Mutable; import cn.hutool.core.lang.mutable.MutableObj; -import cn.hutool.core.map.MapUtil; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.map.WeakConcurrentMap; import java.io.Serializable; import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantLock; @@ -37,7 +36,7 @@ public class SimpleCache implements Iterable>, Serializabl /** * 写的时候每个key一把锁,降低锁的粒度 */ - protected final Map keyLockMap = new ConcurrentHashMap<>(); + protected final Map keyLockMap = new SafeConcurrentHashMap<>(); /** * 构造,默认使用{@link WeakHashMap}实现缓存自动清理 @@ -102,7 +101,7 @@ public class SimpleCache implements Iterable>, Serializabl } if (null == v && null != supplier) { //每个key单独获取一把锁,降低锁的粒度提高并发能力,see pr#1385@Github - final Lock keyLock = MapUtil.computeIfAbsent(this.keyLockMap, key, k -> new ReentrantLock()); + final Lock keyLock = this.keyLockMap.computeIfAbsent(key, k -> new ReentrantLock()); keyLock.lock(); try { // 双重检查,防止在竞争锁的过程中已经有其它线程写入 diff --git a/hutool-core/src/main/java/cn/hutool/core/cache/impl/AbstractCache.java b/hutool-core/src/main/java/cn/hutool/core/cache/impl/AbstractCache.java index d64387d82..6370281ca 100755 --- a/hutool-core/src/main/java/cn/hutool/core/cache/impl/AbstractCache.java +++ b/hutool-core/src/main/java/cn/hutool/core/cache/impl/AbstractCache.java @@ -5,11 +5,11 @@ import cn.hutool.core.cache.CacheListener; import cn.hutool.core.lang.func.SerSupplier; import cn.hutool.core.lang.mutable.Mutable; import cn.hutool.core.lang.mutable.MutableObj; +import cn.hutool.core.map.SafeConcurrentHashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -35,7 +35,7 @@ public abstract class AbstractCache implements Cache { /** * 写的时候每个key一把锁,降低锁的粒度 */ - protected final Map keyLockMap = new ConcurrentHashMap<>(); + protected final Map keyLockMap = new SafeConcurrentHashMap<>(); /** * 返回缓存容量,{@code 0}表示无大小限制 diff --git a/hutool-core/src/main/java/cn/hutool/core/classloader/ClassLoaderUtil.java b/hutool-core/src/main/java/cn/hutool/core/classloader/ClassLoaderUtil.java index 5605ea019..8ed22b45d 100644 --- a/hutool-core/src/main/java/cn/hutool/core/classloader/ClassLoaderUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/classloader/ClassLoaderUtil.java @@ -4,6 +4,7 @@ import cn.hutool.core.convert.BasicType; import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.map.WeakConcurrentMap; import cn.hutool.core.text.CharPool; import cn.hutool.core.text.StrUtil; @@ -15,7 +16,6 @@ import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * {@link ClassLoader}工具类 @@ -49,7 +49,7 @@ public class ClassLoaderUtil { /** * 原始类型名和其class对应表,例如:int =》 int.class */ - private static final Map> PRIMITIVE_TYPE_NAME_MAP = new ConcurrentHashMap<>(32); + private static final Map> PRIMITIVE_TYPE_NAME_MAP = new SafeConcurrentHashMap<>(32); private static final Map, Class> CLASS_CACHE = new WeakConcurrentMap<>(); static { @@ -203,7 +203,7 @@ public class ClassLoaderUtil { if (clazz == null) { final String finalName = name; final ClassLoader finalClassLoader = classLoader; - clazz = MapUtil.computeIfAbsent(CLASS_CACHE, MapUtil.entry(name, classLoader), (key) -> doLoadClass(finalName, finalClassLoader, isInitialized)); + clazz = CLASS_CACHE.computeIfAbsent(MapUtil.entry(name, classLoader), (key) -> doLoadClass(finalName, finalClassLoader, isInitialized)); } return (Class) clazz; } diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java b/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java index 25f470ad3..b3450c96b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/ConcurrentHashSet.java @@ -1,10 +1,11 @@ package cn.hutool.core.collection; +import cn.hutool.core.map.SafeConcurrentHashMap; + import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; /** - * 通过{@link ConcurrentHashMap}实现的线程安全HashSet + * 通过{@link SafeConcurrentHashMap}实现的线程安全HashSet * * @author Looly * @@ -20,7 +21,7 @@ public class ConcurrentHashSet extends SetFromMap { * 触发因子为默认的0.75 */ public ConcurrentHashSet() { - super(new ConcurrentHashMap<>()); + super(new SafeConcurrentHashMap<>()); } /** @@ -30,7 +31,7 @@ public class ConcurrentHashSet extends SetFromMap { * @param initialCapacity 初始大小 */ public ConcurrentHashSet(final int initialCapacity) { - super(new ConcurrentHashMap<>(initialCapacity)); + super(new SafeConcurrentHashMap<>(initialCapacity)); } /** @@ -40,7 +41,7 @@ public class ConcurrentHashSet extends SetFromMap { * @param loadFactor 加载因子。此参数决定数据增长时触发的百分比 */ public ConcurrentHashSet(final int initialCapacity, final float loadFactor) { - super(new ConcurrentHashMap<>(initialCapacity, loadFactor)); + super(new SafeConcurrentHashMap<>(initialCapacity, loadFactor)); } /** @@ -51,7 +52,7 @@ public class ConcurrentHashSet extends SetFromMap { * @param concurrencyLevel 线程并发度 */ public ConcurrentHashSet(final int initialCapacity, final float loadFactor, final int concurrencyLevel) { - super(new ConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel)); + super(new SafeConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel)); } /** @@ -59,7 +60,7 @@ public class ConcurrentHashSet extends SetFromMap { * @param iter {@link Iterable} */ public ConcurrentHashSet(final Iterable iter) { - super(iter instanceof Collection ? new ConcurrentHashMap<>((int)(((Collection)iter).size() / 0.75f)) : new ConcurrentHashMap<>()); + super(iter instanceof Collection ? new SafeConcurrentHashMap<>(((Collection)iter).size()) : new SafeConcurrentHashMap<>()); if(iter instanceof Collection) { this.addAll((Collection)iter); }else { diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/BasicType.java b/hutool-core/src/main/java/cn/hutool/core/convert/BasicType.java index 00835c192..6870bc8b8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/BasicType.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/BasicType.java @@ -1,7 +1,8 @@ package cn.hutool.core.convert; +import cn.hutool.core.map.SafeConcurrentHashMap; + import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * 基本变量类型的枚举
@@ -12,9 +13,9 @@ public enum BasicType { BYTE, SHORT, INT, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, CHAR, CHARACTER, STRING; /** 包装类型为Key,原始类型为Value,例如: Integer.class =》 int.class. */ - public static final Map, Class> WRAPPER_PRIMITIVE_MAP = new ConcurrentHashMap<>(8); + public static final Map, Class> WRAPPER_PRIMITIVE_MAP = new SafeConcurrentHashMap<>(8); /** 原始类型为Key,包装类型为Value,例如: int.class =》 Integer.class. */ - public static final Map, Class> PRIMITIVE_WRAPPER_MAP = new ConcurrentHashMap<>(8); + public static final Map, Class> PRIMITIVE_WRAPPER_MAP = new SafeConcurrentHashMap<>(8); static { WRAPPER_PRIMITIVE_MAP.put(Boolean.class, boolean.class); diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java index 7ff40594a..5a11e1a50 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java @@ -29,6 +29,7 @@ import cn.hutool.core.convert.impl.XMLGregorianCalendarConverter; import cn.hutool.core.convert.impl.ZoneIdConverter; import cn.hutool.core.date.DateTime; import cn.hutool.core.lang.Opt; +import cn.hutool.core.map.SafeConcurrentHashMap; import javax.xml.datatype.XMLGregorianCalendar; import java.io.Serializable; @@ -60,7 +61,6 @@ import java.util.Map; import java.util.Optional; import java.util.TimeZone; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicIntegerArray; import java.util.concurrent.atomic.AtomicLongArray; @@ -176,7 +176,7 @@ public class RegisterConverter implements Converter, Serializable { if (null == customConverterMap) { synchronized (this) { if (null == customConverterMap) { - customConverterMap = new ConcurrentHashMap<>(); + customConverterMap = new SafeConcurrentHashMap<>(); } } } @@ -188,7 +188,7 @@ public class RegisterConverter implements Converter, Serializable { * 注册默认转换器 */ private void registerDefault() { - defaultConverterMap = new ConcurrentHashMap<>(); + defaultConverterMap = new SafeConcurrentHashMap<>(64); // 包装类转换器 defaultConverterMap.put(Character.class, new CharacterConverter()); diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/EnumConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/EnumConverter.java index 62606e3b9..245a35bf3 100755 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/EnumConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/EnumConverter.java @@ -118,7 +118,7 @@ public class EnumConverter extends AbstractConverter { * @return 转换方法map,key为方法参数类型,value为方法 */ private static Map, Method> getMethodMap(final Class enumClass) { - return MapUtil.computeIfAbsent(VALUE_OF_METHOD_CACHE, enumClass, (key) -> Arrays.stream(enumClass.getMethods()) + return VALUE_OF_METHOD_CACHE.computeIfAbsent(enumClass, (key) -> Arrays.stream(enumClass.getMethods()) .filter(ModifierUtil::isStatic) .filter(m -> m.getReturnType() == enumClass) .filter(m -> m.getParameterCount() == 1) diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java b/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java index 7b7dbd518..1d23e0389 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java @@ -2,6 +2,7 @@ package cn.hutool.core.date.format; import cn.hutool.core.date.DateException; import cn.hutool.core.date.format.parser.FastDateParser; +import cn.hutool.core.map.SafeConcurrentHashMap; import java.io.IOException; import java.io.ObjectInputStream; @@ -12,7 +13,6 @@ import java.util.Date; import java.util.List; import java.util.Locale; import java.util.TimeZone; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** @@ -1050,7 +1050,7 @@ public class FastDatePrinter extends SimpleDateBasic implements DatePrinter { // ----------------------------------------------------------------------- - private static final ConcurrentMap C_TIME_ZONE_DISPLAY_CACHE = new ConcurrentHashMap<>(7); + private static final ConcurrentMap C_TIME_ZONE_DISPLAY_CACHE = new SafeConcurrentHashMap<>(7); /** *

diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/FormatCache.java b/hutool-core/src/main/java/cn/hutool/core/date/format/FormatCache.java index 47732346a..6a655a437 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/format/FormatCache.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/format/FormatCache.java @@ -2,13 +2,13 @@ package cn.hutool.core.date.format; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Tuple; +import cn.hutool.core.map.SafeConcurrentHashMap; import java.text.DateFormat; import java.text.Format; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** @@ -24,9 +24,9 @@ abstract class FormatCache { */ static final int NONE = -1; - private final ConcurrentMap cInstanceCache = new ConcurrentHashMap<>(7); + private final ConcurrentMap cInstanceCache = new SafeConcurrentHashMap<>(7); - private static final ConcurrentMap C_DATE_TIME_INSTANCE_CACHE = new ConcurrentHashMap<>(7); + private static final ConcurrentMap C_DATE_TIME_INSTANCE_CACHE = new SafeConcurrentHashMap<>(7); /** * 使用默认的pattern、timezone和locale获得缓存中的实例 diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java b/hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java index 68be9974a..8fdc29d93 100755 --- a/hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/format/GlobalCustomFormat.java @@ -2,11 +2,11 @@ package cn.hutool.core.date.format; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; +import cn.hutool.core.map.SafeConcurrentHashMap; import java.time.temporal.TemporalAccessor; import java.util.Date; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; /** @@ -25,8 +25,8 @@ public class GlobalCustomFormat { private static final Map> parserMap; static { - formatterMap = new ConcurrentHashMap<>(); - parserMap = new ConcurrentHashMap<>(); + formatterMap = new SafeConcurrentHashMap<>(); + parserMap = new SafeConcurrentHashMap<>(); // Hutool预设的几种自定义格式 putFormatter(FORMAT_SECONDS, (date) -> String.valueOf(Math.floorDiv(date.getTime(), 1000))); diff --git a/hutool-core/src/main/java/cn/hutool/core/date/format/parser/FastDateParser.java b/hutool-core/src/main/java/cn/hutool/core/date/format/parser/FastDateParser.java index b4b38bb8f..b38de87bc 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/format/parser/FastDateParser.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/format/parser/FastDateParser.java @@ -3,6 +3,7 @@ package cn.hutool.core.date.format.parser; import cn.hutool.core.date.format.FastDateFormat; import cn.hutool.core.date.format.FastDatePrinter; import cn.hutool.core.date.format.SimpleDateBasic; +import cn.hutool.core.map.SafeConcurrentHashMap; import java.io.IOException; import java.io.ObjectInputStream; @@ -22,7 +23,6 @@ import java.util.Objects; import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -453,7 +453,7 @@ public class FastDateParser extends SimpleDateBasic implements PositionDateParse private static ConcurrentMap getCache(final int field) { synchronized (CACHES) { if (CACHES[field] == null) { - CACHES[field] = new ConcurrentHashMap<>(3); + CACHES[field] = new SafeConcurrentHashMap<>(3); } return CACHES[field]; } 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 6bdb0ddbc..5b12fdf5c 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 @@ -2,13 +2,12 @@ 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.map.SafeConcurrentHashMap; import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; /** @@ -19,7 +18,7 @@ import java.util.stream.Collectors; */ public final class Singleton { - private static final ConcurrentHashMap POOL = new ConcurrentHashMap<>(); + private static final SafeConcurrentHashMap POOL = new SafeConcurrentHashMap<>(); private Singleton() { } @@ -53,7 +52,7 @@ public final class Singleton { */ @SuppressWarnings("unchecked") public static T get(final String key, final SerSupplier supplier) { - return (T) MapUtil.computeIfAbsent(POOL, key, (k)-> supplier.get()); + return (T) POOL.computeIfAbsent(key, (k)-> supplier.get()); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java index df1cb28b7..4bfa0521a 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java @@ -4,7 +4,6 @@ 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; @@ -74,7 +73,7 @@ public class LambdaUtil { * @return 返回解析后的结果 */ public static LambdaInfo resolve(final T func) { - return MapUtil.computeIfAbsent(CACHE, func.getClass().getName(), (key) -> { + return CACHE.computeIfAbsent(func.getClass().getName(), (key) -> { final SerializedLambda serializedLambda = _resolve(func); final String methodName = serializedLambda.getImplMethodName(); final Class implClass; diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/intern/WeakInterner.java b/hutool-core/src/main/java/cn/hutool/core/lang/intern/WeakInterner.java index 1ed536cf6..dd0c0e322 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/intern/WeakInterner.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/intern/WeakInterner.java @@ -1,6 +1,5 @@ package cn.hutool.core.lang.intern; -import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.WeakConcurrentMap; /** @@ -18,6 +17,6 @@ public class WeakInterner implements Interner{ if(null == sample){ return null; } - return MapUtil.computeIfAbsent(cache, sample, (key)->sample); + return cache.computeIfAbsent(sample, (key)->sample); } } diff --git a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java index 257741940..9a8886b3a 100755 --- a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java @@ -1265,16 +1265,16 @@ public class MapUtil extends MapGetUtil { } /** - * 方法来自Dubbo,解决使用ConcurrentHashMap.computeIfAbsent导致的死循环问题。
- * issues#2349
+ * 如果 key 对应的 value 不存在,则使用获取 mappingFunction 重新计算后的值,并保存为该 key 的 value,否则返回 value。
+ * 方法来自Dubbo,解决使用ConcurrentHashMap.computeIfAbsent导致的死循环问题。(issues#2349)
* A temporary workaround for Java 8 specific performance issue JDK-8161372 .
* This class should be removed once we drop Java 8 support. * * @see https://bugs.openjdk.java.net/browse/JDK-8161372 */ - public static V computeIfAbsent(final Map map, final K key, final Function mappingFunction) { + public static V computeIfAbsent(final Map map, final K key, final Function mappingFunction) { V value = map.get(key); - if(null == value){ + if (null == value) { map.putIfAbsent(key, mappingFunction.apply(key)); value = map.get(key); } 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 054ca2653..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 @@ -133,7 +133,7 @@ public class ReferenceConcurrentMap implements ConcurrentMap, Iterab @Override public V computeIfAbsent(final K key, final Function mappingFunction) { this.purgeStaleKeys(); - return MapUtil.computeIfAbsent(this.raw, ofKey(key, this.lastQueue), kWeakKey -> mappingFunction.apply(key)); + return this.raw.computeIfAbsent(ofKey(key, this.lastQueue), kWeakKey -> mappingFunction.apply(key)); } @Override diff --git a/hutool-core/src/main/java/cn/hutool/core/map/SafeConcurrentHashMap.java b/hutool-core/src/main/java/cn/hutool/core/map/SafeConcurrentHashMap.java new file mode 100644 index 000000000..4eccc900e --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/map/SafeConcurrentHashMap.java @@ -0,0 +1,74 @@ +package cn.hutool.core.map; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +/** + * 安全的ConcurrentHashMap实现
+ * 此类用于解决在JDK8中调用{@link ConcurrentHashMap#computeIfAbsent(Object, Function)}可能造成的死循环问题。
+ * 方法来自Dubbo,见:issues#2349
+ *

+ * 相关bug见:@see https://bugs.openjdk.java.net/browse/JDK-8161372 + * + * @param 键类型 + * @param 值类型 + */ +public class SafeConcurrentHashMap extends ConcurrentHashMap { + private static final long serialVersionUID = 1L; + + // region == 构造 == + + /** + * 构造,默认初始大小(16) + */ + public SafeConcurrentHashMap() { + super(); + } + + /** + * 构造 + * + * @param initialCapacity 预估初始大小 + */ + public SafeConcurrentHashMap(int initialCapacity) { + super(initialCapacity); + } + + /** + * 构造 + * + * @param m 初始键值对 + */ + public SafeConcurrentHashMap(Map m) { + super(m); + } + + /** + * 构造 + * + * @param initialCapacity 初始容量 + * @param loadFactor 增长系数 + */ + public SafeConcurrentHashMap(int initialCapacity, float loadFactor) { + super(initialCapacity, loadFactor); + } + + /** + * 构造 + * + * @param initialCapacity 初始容量 + * @param loadFactor 增长系数 + * @param concurrencyLevel 并发级别,即Segment的个数 + */ + public SafeConcurrentHashMap(int initialCapacity, + float loadFactor, int concurrencyLevel) { + super(initialCapacity, loadFactor, concurrencyLevel); + } + // endregion == 构造 == + + @Override + public V computeIfAbsent(K key, Function mappingFunction) { + return MapUtil.computeIfAbsent(this, key, mappingFunction); + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/map/WeakConcurrentMap.java b/hutool-core/src/main/java/cn/hutool/core/map/WeakConcurrentMap.java index 4dee60b9e..7e4b86852 100755 --- a/hutool-core/src/main/java/cn/hutool/core/map/WeakConcurrentMap.java +++ b/hutool-core/src/main/java/cn/hutool/core/map/WeakConcurrentMap.java @@ -3,7 +3,6 @@ package cn.hutool.core.map; import cn.hutool.core.util.ReferenceUtil; import java.lang.ref.Reference; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** @@ -16,12 +15,13 @@ import java.util.concurrent.ConcurrentMap; * @since 5.8.0 */ public class WeakConcurrentMap extends ReferenceConcurrentMap { + private static final long serialVersionUID = 1L; /** * 构造 */ public WeakConcurrentMap() { - this(new ConcurrentHashMap<>()); + this(new SafeConcurrentHashMap<>()); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/ActualTypeMapperPool.java b/hutool-core/src/main/java/cn/hutool/core/reflect/ActualTypeMapperPool.java index 6243cba39..92f5e3a5a 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/ActualTypeMapperPool.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/ActualTypeMapperPool.java @@ -1,7 +1,6 @@ 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; @@ -27,7 +26,7 @@ public class ActualTypeMapperPool { * @return 泛型对应关系Map */ public static Map get(final Type type) { - return MapUtil.computeIfAbsent(CACHE, type, (key) -> createTypeMap(type)); + return CACHE.computeIfAbsent(type, (key) -> createTypeMap(type)); } /** 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 9f31a90f7..016274c4e 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 @@ -2,7 +2,6 @@ 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; @@ -65,7 +64,7 @@ public class ConstructorUtil { @SuppressWarnings("unchecked") public static Constructor[] getConstructors(final Class beanClass) throws SecurityException { Assert.notNull(beanClass); - return (Constructor[]) MapUtil.computeIfAbsent(CONSTRUCTORS_CACHE, beanClass, (key) -> 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 24b11b323..c52728c6e 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 MapUtil.computeIfAbsent(FIELDS_CACHE, beanClass, (key) -> 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 8a95d527e..6b212c9d2 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 @@ -9,7 +9,6 @@ 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; @@ -320,7 +319,7 @@ public class MethodUtil { */ public static Method[] getMethods(final Class beanClass) throws SecurityException { Assert.notNull(beanClass); - return MapUtil.computeIfAbsent(METHODS_CACHE, beanClass, + return METHODS_CACHE.computeIfAbsent(beanClass, (key) -> getMethodsDirectly(beanClass, true, true)); } diff --git a/hutool-core/src/main/java/cn/hutool/core/regex/PatternPool.java b/hutool-core/src/main/java/cn/hutool/core/regex/PatternPool.java index 021f535fb..0f7861919 100755 --- a/hutool-core/src/main/java/cn/hutool/core/regex/PatternPool.java +++ b/hutool-core/src/main/java/cn/hutool/core/regex/PatternPool.java @@ -1,6 +1,5 @@ package cn.hutool.core.regex; -import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.WeakConcurrentMap; import java.util.regex.Pattern; @@ -198,7 +197,7 @@ public class PatternPool { */ public static Pattern get(final String regex, final int flags) { final RegexWithFlag regexWithFlag = new RegexWithFlag(regex, flags); - return MapUtil.computeIfAbsent(POOL, regexWithFlag, (key) -> Pattern.compile(regex, flags)); + return POOL.computeIfAbsent(regexWithFlag, (key) -> Pattern.compile(regex, flags)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java b/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java index b90b911d4..d209d63dc 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/TransformableWrappedStream.java @@ -6,13 +6,22 @@ import cn.hutool.core.lang.Console; import cn.hutool.core.lang.mutable.MutableInt; import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.util.ArrayUtil; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.*; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -221,7 +230,7 @@ public interface TransformableWrappedStream EasyStream distinct(final Function keyExtractor) { Objects.requireNonNull(keyExtractor); if (isParallel()) { - final ConcurrentHashMap exists = MapUtil.newConcurrentHashMap(); + final SafeConcurrentHashMap exists = new SafeConcurrentHashMap<>(); // 标记是否出现过null值,用于保留第一个出现的null // 由于ConcurrentHashMap的key不能为null,所以用此变量来标记 final AtomicBoolean hasNull = new AtomicBoolean(false); diff --git a/hutool-core/src/main/java/cn/hutool/core/text/AntPathMatcher.java b/hutool-core/src/main/java/cn/hutool/core/text/AntPathMatcher.java index e61b63ee5..cffdfa3ae 100755 --- a/hutool-core/src/main/java/cn/hutool/core/text/AntPathMatcher.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/AntPathMatcher.java @@ -1,6 +1,7 @@ package cn.hutool.core.text; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.text.split.SplitUtil; import java.util.ArrayList; @@ -8,7 +9,6 @@ import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -62,9 +62,9 @@ public class AntPathMatcher { private volatile Boolean cachePatterns; - private final Map tokenizedPatternCache = new ConcurrentHashMap<>(256); + private final Map tokenizedPatternCache = new SafeConcurrentHashMap<>(256); - private final Map stringMatcherCache = new ConcurrentHashMap<>(256); + private final Map stringMatcherCache = new SafeConcurrentHashMap<>(256); /** diff --git a/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java index cdba6223e..2e0486494 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java @@ -1,11 +1,11 @@ package cn.hutool.core.util; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.regex.PatternPool; import cn.hutool.core.regex.ReUtil; import cn.hutool.core.text.StrUtil; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; /** @@ -38,7 +38,7 @@ public class CreditCodeUtil { private static final Map CODE_INDEX_MAP; static { - CODE_INDEX_MAP = new ConcurrentHashMap<>(); + CODE_INDEX_MAP = new SafeConcurrentHashMap<>(); for (int i = 0; i < BASE_CODE_ARRAY.length; i++) { CODE_INDEX_MAP.put(BASE_CODE_ARRAY[i], i); } diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java index 6e303659d..2ebbfd7cf 100755 --- a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java @@ -1,6 +1,7 @@ package cn.hutool.db.dialect; import cn.hutool.core.classloader.ClassLoaderUtil; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.regex.ReUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.db.dialect.impl.AnsiSqlDialect; @@ -16,7 +17,6 @@ import cn.hutool.log.StaticLog; import javax.sql.DataSource; import java.sql.Connection; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * 方言工厂类 @@ -26,7 +26,7 @@ import java.util.concurrent.ConcurrentHashMap; */ public class DialectFactory implements DriverNamePool{ - private static final Map DIALECT_POOL = new ConcurrentHashMap<>(); + private static final Map DIALECT_POOL = new SafeConcurrentHashMap<>(); private DialectFactory() { } @@ -170,11 +170,7 @@ public class DialectFactory implements DriverNamePool{ // 数据源作为锁的意义在于:不同数据源不会导致阻塞,相同数据源获取方言时可保证互斥 //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (ds) { - dialect = DIALECT_POOL.get(ds); - if(null == dialect) { - dialect = newDialect(ds); - DIALECT_POOL.put(ds, dialect); - } + dialect = DIALECT_POOL.computeIfAbsent(ds, DialectFactory::newDialect); } } return dialect; diff --git a/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java b/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java index d3d5be7e8..7dd3d5569 100644 --- a/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java +++ b/hutool-db/src/main/java/cn/hutool/db/ds/AbstractDSFactory.java @@ -2,6 +2,7 @@ package cn.hutool.db.ds; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.text.StrUtil; import cn.hutool.db.DbRuntimeException; import cn.hutool.db.DbUtil; @@ -12,7 +13,6 @@ import cn.hutool.setting.Setting; import javax.sql.DataSource; import java.util.Collection; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * 抽象数据源工厂
@@ -54,7 +54,7 @@ public abstract class AbstractDSFactory extends DSFactory { DbUtil.setShowSqlGlobal(setting); this.setting = setting; - this.dsMap = new ConcurrentHashMap<>(); + this.dsMap = new SafeConcurrentHashMap<>(); } /** diff --git a/hutool-db/src/main/java/cn/hutool/db/meta/JdbcType.java b/hutool-db/src/main/java/cn/hutool/db/meta/JdbcType.java index 52d01797c..cee36bc26 100644 --- a/hutool-db/src/main/java/cn/hutool/db/meta/JdbcType.java +++ b/hutool-db/src/main/java/cn/hutool/db/meta/JdbcType.java @@ -1,7 +1,7 @@ package cn.hutool.db.meta; +import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * JDBC中字段类型枚举 @@ -63,7 +63,8 @@ public enum JdbcType { this.typeCode = code; } - private static final Map CODE_MAP = new ConcurrentHashMap<>(100, 1); + // 此处无写操作,使用HashMap没有线程安全问题 + private static final Map CODE_MAP = new HashMap<>(128, 1); static { for (final JdbcType type : JdbcType.values()) { CODE_MAP.put(type.typeCode, type); @@ -74,7 +75,7 @@ public enum JdbcType { * 通过{@link java.sql.Types}中对应int值找到enum值 * * @param code Jdbc type值 - * @return {@link JdbcType} + * @return {@code JdbcType} */ public static JdbcType valueOf(final int code) { return CODE_MAP.get(code); 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 76f556a45..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 @@ -1,6 +1,5 @@ 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; @@ -44,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 MapUtil.computeIfAbsent(cache, key, (k) -> BeanCopier.create(srcClass, targetClass, useConverter)); + return cache.computeIfAbsent(key, (k) -> BeanCopier.create(srcClass, targetClass, useConverter)); } /** diff --git a/hutool-extra/src/main/java/cn/hutool/extra/script/ScriptUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/script/ScriptUtil.java index 7321fe850..5d1000c7e 100644 --- a/hutool-extra/src/main/java/cn/hutool/extra/script/ScriptUtil.java +++ b/hutool-extra/src/main/java/cn/hutool/extra/script/ScriptUtil.java @@ -1,7 +1,6 @@ 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; @@ -31,7 +30,7 @@ public class ScriptUtil { * @return {@link ScriptEngine} 实例 */ public static ScriptEngine getScript(final String nameOrExtOrMime) { - return MapUtil.computeIfAbsent(CACHE, nameOrExtOrMime, (key) -> createScript(nameOrExtOrMime)); + return CACHE.computeIfAbsent(nameOrExtOrMime, (key) -> createScript(nameOrExtOrMime)); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java b/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java index de2a64692..dc1e337c8 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java +++ b/hutool-http/src/main/java/cn/hutool/http/HTMLFilter.java @@ -1,6 +1,7 @@ package cn.hutool.http; import cn.hutool.core.lang.Console; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.util.CharUtil; import java.util.ArrayList; @@ -8,7 +9,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -61,8 +61,8 @@ public final class HTMLFilter { private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); // @xxx could grow large... maybe use sesat's ReferenceMap - private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); - private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new SafeConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new SafeConcurrentHashMap<>(); /** * set of allowed html elements, along with allowed attributes for each element diff --git a/hutool-json/src/main/java/cn/hutool/json/serialize/GlobalSerializeMapping.java b/hutool-json/src/main/java/cn/hutool/json/serialize/GlobalSerializeMapping.java index 7228a1cc7..3ccad807d 100644 --- a/hutool-json/src/main/java/cn/hutool/json/serialize/GlobalSerializeMapping.java +++ b/hutool-json/src/main/java/cn/hutool/json/serialize/GlobalSerializeMapping.java @@ -1,5 +1,6 @@ package cn.hutool.json.serialize; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.json.JSON; import java.lang.reflect.Type; @@ -22,8 +23,8 @@ public class GlobalSerializeMapping { private static Map> deserializerMap; static { - serializerMap = new ConcurrentHashMap<>(); - deserializerMap = new ConcurrentHashMap<>(); + serializerMap = new SafeConcurrentHashMap<>(); + deserializerMap = new SafeConcurrentHashMap<>(); final TemporalAccessorSerializer localDateSerializer = new TemporalAccessorSerializer(LocalDate.class); serializerMap.put(LocalDate.class, localDateSerializer); diff --git a/hutool-log/src/main/java/cn/hutool/log/LogFactory.java b/hutool-log/src/main/java/cn/hutool/log/LogFactory.java index 8295c8046..f213dcb66 100644 --- a/hutool-log/src/main/java/cn/hutool/log/LogFactory.java +++ b/hutool-log/src/main/java/cn/hutool/log/LogFactory.java @@ -2,13 +2,13 @@ package cn.hutool.log; import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.lang.caller.CallerUtil; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.util.ServiceLoaderUtil; import cn.hutool.log.dialect.console.ConsoleLogFactory; import cn.hutool.log.dialect.jdk.JdkLogFactory; import java.net.URL; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * 日志工厂类 @@ -33,7 +33,7 @@ public abstract class LogFactory { */ public LogFactory(final String name) { this.name = name; - logCache = new ConcurrentHashMap<>(); + logCache = new SafeConcurrentHashMap<>(); } /** diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java index be120e751..8d7da672c 100755 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelWriter.java @@ -9,6 +9,7 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.id.IdUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.map.TableMap; import cn.hutool.core.map.multi.RowKeyTable; import cn.hutool.core.map.multi.Table; @@ -44,7 +45,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; /** @@ -59,6 +59,7 @@ import java.util.concurrent.atomic.AtomicInteger; * @author Looly * @since 3.2.0 */ +@SuppressWarnings("resource") public class ExcelWriter extends ExcelBase { /** @@ -938,7 +939,7 @@ public class ExcelWriter extends ExcelBase { */ public ExcelWriter writeHeadRow(final Iterable rowData) { Assert.isFalse(this.isClosed, "ExcelWriter has been closed!"); - this.headLocationCache = new ConcurrentHashMap<>(); + this.headLocationCache = new SafeConcurrentHashMap<>(); final Row row = this.sheet.createRow(this.currentRow.getAndIncrement()); int i = 0; Cell cell; diff --git a/hutool-setting/src/main/java/cn/hutool/setting/SettingUtil.java b/hutool-setting/src/main/java/cn/hutool/setting/SettingUtil.java index 151dd945e..8b2d78739 100644 --- a/hutool-setting/src/main/java/cn/hutool/setting/SettingUtil.java +++ b/hutool-setting/src/main/java/cn/hutool/setting/SettingUtil.java @@ -2,10 +2,10 @@ package cn.hutool.setting; import cn.hutool.core.io.file.FileNameUtil; import cn.hutool.core.io.resource.NoResourceException; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.text.StrUtil; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * Setting工具类
@@ -17,7 +17,7 @@ public class SettingUtil { /** * 配置文件缓存 */ - private static final Map SETTING_MAP = new ConcurrentHashMap<>(); + private static final Map SETTING_MAP = new SafeConcurrentHashMap<>(); /** * 获取当前环境下的配置文件
diff --git a/hutool-setting/src/main/java/cn/hutool/setting/dialect/PropsUtil.java b/hutool-setting/src/main/java/cn/hutool/setting/dialect/PropsUtil.java index 996e0d32c..745842ecf 100644 --- a/hutool-setting/src/main/java/cn/hutool/setting/dialect/PropsUtil.java +++ b/hutool-setting/src/main/java/cn/hutool/setting/dialect/PropsUtil.java @@ -2,10 +2,10 @@ package cn.hutool.setting.dialect; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.resource.NoResourceException; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.text.StrUtil; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * Props工具类
@@ -19,7 +19,7 @@ public class PropsUtil { /** * 配置文件缓存 */ - private static final Map propsMap = new ConcurrentHashMap<>(); + private static final Map propsMap = new SafeConcurrentHashMap<>(); /** * 获取当前环境下的配置文件
diff --git a/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java b/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java index 73d680c47..5a9abf66e 100755 --- a/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java +++ b/hutool-setting/src/main/java/cn/hutool/setting/profile/Profile.java @@ -1,13 +1,13 @@ package cn.hutool.setting.profile; import cn.hutool.core.lang.Assert; +import cn.hutool.core.map.SafeConcurrentHashMap; import cn.hutool.core.text.StrUtil; import cn.hutool.setting.Setting; import java.io.Serializable; import java.nio.charset.Charset; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * Profile可以让我们定义一系列的配置信息,然后指定其激活条件。
@@ -36,7 +36,7 @@ public class Profile implements Serializable { /** 是否使用变量 */ private boolean useVar; /** 配置文件缓存 */ - private final Map settingMap = new ConcurrentHashMap<>(); + private final Map settingMap = new SafeConcurrentHashMap<>(); // -------------------------------------------------------------------------------- Constructor start /**