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 034a2334b..adad6683a 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,6 +4,7 @@ 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.WeakConcurrentMap; import java.io.Serializable; @@ -101,7 +102,7 @@ public class SimpleCache implements Iterable>, Serializabl } if (null == v && null != supplier) { //每个key单独获取一把锁,降低锁的粒度提高并发能力,see pr#1385@Github - final Lock keyLock = keyLockMap.computeIfAbsent(key, k -> new ReentrantLock()); + final Lock keyLock = MapUtil.computeIfAbsent(this.keyLockMap, key, k -> new ReentrantLock()); keyLock.lock(); try { // 双重检查,防止在竞争锁的过程中已经有其它线程写入 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 240cfd09e..07f6ae319 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 @@ -1263,4 +1263,19 @@ public class MapUtil extends MapGetUtil { } return map; } + + /** + * 方法来自MyBatis,解决使用ConcurrentHashMap.computeIfAbsent导致的死循环问题。
+ * 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) { + final V value = map.get(key); + if (value != null) { + return value; + } + return map.computeIfAbsent(key, mappingFunction); + } } 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 6e7d43212..054ca2653 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 this.raw.computeIfAbsent(ofKey(key, this.lastQueue), kWeakKey -> mappingFunction.apply(key)); + return MapUtil.computeIfAbsent(this.raw, ofKey(key, this.lastQueue), kWeakKey -> mappingFunction.apply(key)); } @Override