diff --git a/CHANGELOG.md b/CHANGELOG.md index e20d7036b..0583d2bd6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.8.7.M1 (2022-09-13) +# 5.8.7.M1 (2022-09-14) ### 🐣新特性 * 【core 】 BooleanUtil的andOfWrap和orOfWrap()忽略null(issue#2599@Github) @@ -11,6 +11,7 @@ ### 🐞Bug修复 * 【core 】 修复ObjectUtil.defaultIfXXX中NPE问题(pr#2603@Github) * 【db 】 修复Hive2驱动无法识别问题(issue#2606@Github) +* 【core 】 修复computeIfAbsent问题(issue#I5PTN3@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/SimpleCache.java b/hutool-core/src/main/java/cn/hutool/core/lang/SimpleCache.java index 332723c7b..67c1c6ece 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/SimpleCache.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/SimpleCache.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.TransIter; import cn.hutool.core.lang.func.Func0; 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 59a612801..2c13bd22a 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 @@ -12,10 +12,25 @@ import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; -import java.util.*; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.NavigableMap; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; +import java.util.function.Function; /** * Map相关工具类 @@ -1447,4 +1462,19 @@ public class MapUtil { new AbstractMap.SimpleImmutableEntry<>(key, value) : new AbstractMap.SimpleEntry<>(key, value); } + + /** + * 方法来自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(Map map, K key, 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 99e80a877..5137d7ba9 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 @@ -134,7 +134,7 @@ public class ReferenceConcurrentMap implements ConcurrentMap, Iterab @Override public V computeIfAbsent(K key, 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