mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add SafeConcurrentHashMap
This commit is contained in:
parent
cf0fc45080
commit
3b5ba16c93
@ -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<ResolvedAnnotationMapping> 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<GenericAnnotationMapping> 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))
|
||||
));
|
||||
}
|
||||
|
@ -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<T extends Annotation> implements Invoc
|
||||
private AnnotationMappingProxy(final AnnotationMapping<T> 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();
|
||||
}
|
||||
|
@ -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<BeanDesc> supplier) {
|
||||
return MapUtil.computeIfAbsent(bdCache, beanClass, (key) -> supplier.get());
|
||||
return bdCache.computeIfAbsent(beanClass, (key) -> supplier.get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<K, V> implements Iterable<Map.Entry<K, V>>, Serializabl
|
||||
/**
|
||||
* 写的时候每个key一把锁,降低锁的粒度
|
||||
*/
|
||||
protected final Map<K, Lock> keyLockMap = new ConcurrentHashMap<>();
|
||||
protected final Map<K, Lock> keyLockMap = new SafeConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 构造,默认使用{@link WeakHashMap}实现缓存自动清理
|
||||
@ -102,7 +101,7 @@ public class SimpleCache<K, V> implements Iterable<Map.Entry<K, V>>, 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 {
|
||||
// 双重检查,防止在竞争锁的过程中已经有其它线程写入
|
||||
|
@ -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<K, V> implements Cache<K, V> {
|
||||
/**
|
||||
* 写的时候每个key一把锁,降低锁的粒度
|
||||
*/
|
||||
protected final Map<K, Lock> keyLockMap = new ConcurrentHashMap<>();
|
||||
protected final Map<K, Lock> keyLockMap = new SafeConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 返回缓存容量,{@code 0}表示无大小限制
|
||||
|
@ -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<String, Class<?>> PRIMITIVE_TYPE_NAME_MAP = new ConcurrentHashMap<>(32);
|
||||
private static final Map<String, Class<?>> PRIMITIVE_TYPE_NAME_MAP = new SafeConcurrentHashMap<>(32);
|
||||
private static final Map<Map.Entry<String, ClassLoader>, 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<T>) clazz;
|
||||
}
|
||||
|
@ -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<E> extends SetFromMap<E> {
|
||||
* 触发因子为默认的0.75
|
||||
*/
|
||||
public ConcurrentHashSet() {
|
||||
super(new ConcurrentHashMap<>());
|
||||
super(new SafeConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -30,7 +31,7 @@ public class ConcurrentHashSet<E> extends SetFromMap<E> {
|
||||
* @param initialCapacity 初始大小
|
||||
*/
|
||||
public ConcurrentHashSet(final int initialCapacity) {
|
||||
super(new ConcurrentHashMap<>(initialCapacity));
|
||||
super(new SafeConcurrentHashMap<>(initialCapacity));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,7 +41,7 @@ public class ConcurrentHashSet<E> extends SetFromMap<E> {
|
||||
* @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<E> extends SetFromMap<E> {
|
||||
* @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<E> extends SetFromMap<E> {
|
||||
* @param iter {@link Iterable}
|
||||
*/
|
||||
public ConcurrentHashSet(final Iterable<E> iter) {
|
||||
super(iter instanceof Collection ? new ConcurrentHashMap<>((int)(((Collection<E>)iter).size() / 0.75f)) : new ConcurrentHashMap<>());
|
||||
super(iter instanceof Collection ? new SafeConcurrentHashMap<>(((Collection<E>)iter).size()) : new SafeConcurrentHashMap<>());
|
||||
if(iter instanceof Collection) {
|
||||
this.addAll((Collection<E>)iter);
|
||||
}else {
|
||||
|
@ -1,7 +1,8 @@
|
||||
package cn.hutool.core.convert;
|
||||
|
||||
import cn.hutool.core.map.SafeConcurrentHashMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 基本变量类型的枚举<br>
|
||||
@ -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<?>, Class<?>> WRAPPER_PRIMITIVE_MAP = new ConcurrentHashMap<>(8);
|
||||
public static final Map<Class<?>, Class<?>> WRAPPER_PRIMITIVE_MAP = new SafeConcurrentHashMap<>(8);
|
||||
/** 原始类型为Key,包装类型为Value,例如: int.class =》 Integer.class. */
|
||||
public static final Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_MAP = new ConcurrentHashMap<>(8);
|
||||
public static final Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_MAP = new SafeConcurrentHashMap<>(8);
|
||||
|
||||
static {
|
||||
WRAPPER_PRIMITIVE_MAP.put(Boolean.class, boolean.class);
|
||||
|
@ -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());
|
||||
|
@ -118,7 +118,7 @@ public class EnumConverter extends AbstractConverter {
|
||||
* @return 转换方法map,key为方法参数类型,value为方法
|
||||
*/
|
||||
private static Map<Class<?>, 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)
|
||||
|
@ -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<TimeZoneDisplayKey, String> C_TIME_ZONE_DISPLAY_CACHE = new ConcurrentHashMap<>(7);
|
||||
private static final ConcurrentMap<TimeZoneDisplayKey, String> C_TIME_ZONE_DISPLAY_CACHE = new SafeConcurrentHashMap<>(7);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -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<F extends Format> {
|
||||
*/
|
||||
static final int NONE = -1;
|
||||
|
||||
private final ConcurrentMap<Tuple, F> cInstanceCache = new ConcurrentHashMap<>(7);
|
||||
private final ConcurrentMap<Tuple, F> cInstanceCache = new SafeConcurrentHashMap<>(7);
|
||||
|
||||
private static final ConcurrentMap<Tuple, String> C_DATE_TIME_INSTANCE_CACHE = new ConcurrentHashMap<>(7);
|
||||
private static final ConcurrentMap<Tuple, String> C_DATE_TIME_INSTANCE_CACHE = new SafeConcurrentHashMap<>(7);
|
||||
|
||||
/**
|
||||
* 使用默认的pattern、timezone和locale获得缓存中的实例
|
||||
|
@ -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<CharSequence, Function<CharSequence, Date>> 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)));
|
||||
|
@ -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<Locale, Strategy> getCache(final int field) {
|
||||
synchronized (CACHES) {
|
||||
if (CACHES[field] == null) {
|
||||
CACHES[field] = new ConcurrentHashMap<>(3);
|
||||
CACHES[field] = new SafeConcurrentHashMap<>(3);
|
||||
}
|
||||
return CACHES[field];
|
||||
}
|
||||
|
@ -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<String, Object> POOL = new ConcurrentHashMap<>();
|
||||
private static final SafeConcurrentHashMap<String, Object> POOL = new SafeConcurrentHashMap<>();
|
||||
|
||||
private Singleton() {
|
||||
}
|
||||
@ -53,7 +52,7 @@ public final class Singleton {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T get(final String key, final SerSupplier<T> supplier) {
|
||||
return (T) MapUtil.computeIfAbsent(POOL, key, (k)-> supplier.get());
|
||||
return (T) POOL.computeIfAbsent(key, (k)-> supplier.get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 <T extends Serializable> 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;
|
||||
|
@ -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<T> implements Interner<T>{
|
||||
if(null == sample){
|
||||
return null;
|
||||
}
|
||||
return MapUtil.computeIfAbsent(cache, sample, (key)->sample);
|
||||
return cache.computeIfAbsent(sample, (key)->sample);
|
||||
}
|
||||
}
|
||||
|
@ -1265,16 +1265,16 @@ public class MapUtil extends MapGetUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法来自Dubbo,解决使用ConcurrentHashMap.computeIfAbsent导致的死循环问题。<br>
|
||||
* issues#2349<br>
|
||||
* 如果 key 对应的 value 不存在,则使用获取 mappingFunction 重新计算后的值,并保存为该 key 的 value,否则返回 value。<br>
|
||||
* 方法来自Dubbo,解决使用ConcurrentHashMap.computeIfAbsent导致的死循环问题。(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) {
|
||||
public static <K, V> V computeIfAbsent(final Map<K, V> map, final K key, final Function<? super K, ? extends V> mappingFunction) {
|
||||
V value = map.get(key);
|
||||
if(null == value){
|
||||
if (null == value) {
|
||||
map.putIfAbsent(key, mappingFunction.apply(key));
|
||||
value = map.get(key);
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ public class ReferenceConcurrentMap<K, V> implements ConcurrentMap<K, V>, Iterab
|
||||
@Override
|
||||
public V computeIfAbsent(final K key, final Function<? super K, ? extends V> 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
|
||||
|
@ -0,0 +1,74 @@
|
||||
package cn.hutool.core.map;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 安全的ConcurrentHashMap实现<br>
|
||||
* 此类用于解决在JDK8中调用{@link ConcurrentHashMap#computeIfAbsent(Object, Function)}可能造成的死循环问题。<br>
|
||||
* 方法来自Dubbo,见:issues#2349<br>
|
||||
* <p>
|
||||
* 相关bug见:@see <a href="https://bugs.openjdk.java.net/browse/JDK-8161372">https://bugs.openjdk.java.net/browse/JDK-8161372</a>
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
*/
|
||||
public class SafeConcurrentHashMap<K, V> extends ConcurrentHashMap<K, V> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// region == 构造 ==
|
||||
|
||||
/**
|
||||
* 构造,默认初始大小(16)
|
||||
*/
|
||||
public SafeConcurrentHashMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param initialCapacity 预估初始大小
|
||||
*/
|
||||
public SafeConcurrentHashMap(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param m 初始键值对
|
||||
*/
|
||||
public SafeConcurrentHashMap(Map<? extends K, ? extends V> 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<? super K, ? extends V> mappingFunction) {
|
||||
return MapUtil.computeIfAbsent(this, key, mappingFunction);
|
||||
}
|
||||
}
|
@ -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<K, V> extends ReferenceConcurrentMap<K, V> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public WeakConcurrentMap() {
|
||||
this(new ConcurrentHashMap<>());
|
||||
this(new SafeConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<Type, Type> get(final Type type) {
|
||||
return MapUtil.computeIfAbsent(CACHE, type, (key) -> createTypeMap(type));
|
||||
return CACHE.computeIfAbsent(type, (key) -> createTypeMap(type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 <T> Constructor<T>[] getConstructors(final Class<T> beanClass) throws SecurityException {
|
||||
Assert.notNull(beanClass);
|
||||
return (Constructor<T>[]) MapUtil.computeIfAbsent(CONSTRUCTORS_CACHE, beanClass, (key) -> getConstructorsDirectly(beanClass));
|
||||
return (Constructor<T>[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, (key) -> getConstructorsDirectly(beanClass));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<T, S extends TransformableWrappedStr
|
||||
default <F> EasyStream<T> distinct(final Function<? super T, F> keyExtractor) {
|
||||
Objects.requireNonNull(keyExtractor);
|
||||
if (isParallel()) {
|
||||
final ConcurrentHashMap<F, Boolean> exists = MapUtil.newConcurrentHashMap();
|
||||
final SafeConcurrentHashMap<F, Boolean> exists = new SafeConcurrentHashMap<>();
|
||||
// 标记是否出现过null值,用于保留第一个出现的null
|
||||
// 由于ConcurrentHashMap的key不能为null,所以用此变量来标记
|
||||
final AtomicBoolean hasNull = new AtomicBoolean(false);
|
||||
|
@ -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<String, String[]> tokenizedPatternCache = new ConcurrentHashMap<>(256);
|
||||
private final Map<String, String[]> tokenizedPatternCache = new SafeConcurrentHashMap<>(256);
|
||||
|
||||
private final Map<String, AntPathStringMatcher> stringMatcherCache = new ConcurrentHashMap<>(256);
|
||||
private final Map<String, AntPathStringMatcher> stringMatcherCache = new SafeConcurrentHashMap<>(256);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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<Character, Integer> 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);
|
||||
}
|
||||
|
@ -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<DataSource, Dialect> DIALECT_POOL = new ConcurrentHashMap<>();
|
||||
private static final Map<DataSource, Dialect> 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;
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
* 抽象数据源工厂<br>
|
||||
@ -54,7 +54,7 @@ public abstract class AbstractDSFactory extends DSFactory {
|
||||
DbUtil.setShowSqlGlobal(setting);
|
||||
|
||||
this.setting = setting;
|
||||
this.dsMap = new ConcurrentHashMap<>();
|
||||
this.dsMap = new SafeConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<Integer, JdbcType> CODE_MAP = new ConcurrentHashMap<>(100, 1);
|
||||
// 此处无写操作,使用HashMap没有线程安全问题
|
||||
private static final Map<Integer, JdbcType> 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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new SafeConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new SafeConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* set of allowed html elements, along with allowed attributes for each element
|
||||
|
@ -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<Type, JSONDeserializer<?>> 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);
|
||||
|
@ -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<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<ExcelWriter> {
|
||||
|
||||
/**
|
||||
@ -938,7 +939,7 @@ public class ExcelWriter extends ExcelBase<ExcelWriter> {
|
||||
*/
|
||||
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;
|
||||
|
@ -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工具类<br>
|
||||
@ -17,7 +17,7 @@ public class SettingUtil {
|
||||
/**
|
||||
* 配置文件缓存
|
||||
*/
|
||||
private static final Map<String, Setting> SETTING_MAP = new ConcurrentHashMap<>();
|
||||
private static final Map<String, Setting> SETTING_MAP = new SafeConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取当前环境下的配置文件<br>
|
||||
|
@ -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工具类<br>
|
||||
@ -19,7 +19,7 @@ public class PropsUtil {
|
||||
/**
|
||||
* 配置文件缓存
|
||||
*/
|
||||
private static final Map<String, Props> propsMap = new ConcurrentHashMap<>();
|
||||
private static final Map<String, Props> propsMap = new SafeConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取当前环境下的配置文件<br>
|
||||
|
@ -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可以让我们定义一系列的配置信息,然后指定其激活条件。<br>
|
||||
@ -36,7 +36,7 @@ public class Profile implements Serializable {
|
||||
/** 是否使用变量 */
|
||||
private boolean useVar;
|
||||
/** 配置文件缓存 */
|
||||
private final Map<String, Setting> settingMap = new ConcurrentHashMap<>();
|
||||
private final Map<String, Setting> settingMap = new SafeConcurrentHashMap<>();
|
||||
|
||||
// -------------------------------------------------------------------------------- Constructor start
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user