mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
修复SafeConcurrentHashMap.computeIfAbsent可能存在的结果为null的情况
This commit is contained in:
parent
8ceaaa6428
commit
84e8456377
@ -2,7 +2,7 @@
|
||||
# 🚀Changelog
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
# 5.8.17.M1 (2023-04-01)
|
||||
# 5.8.17.M1 (2023-04-02)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 SerializeUtil.deserialize增加白名单类,避免RCE vulnerability(issue#3021@Github)
|
||||
@ -17,6 +17,7 @@
|
||||
### 🐞Bug修复
|
||||
* 【core 】 CollUtil.split优化切割列表参数判断,避免OOM(pr#3026@Github)
|
||||
* 【core 】 修复FileUtil.move传入相同目录或子目录丢失源目录的问题(pr#3032@Github)
|
||||
* 【core 】 修复SafeConcurrentHashMap.computeIfAbsent可能存在的结果为null的情况(issue#I6RVMY@Gitee)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
# 5.8.16 (2023-03-26)
|
||||
|
@ -1481,17 +1481,46 @@ public class MapUtil {
|
||||
*/
|
||||
public static <K, V> V computeIfAbsent(Map<K, V> map, K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
if (JdkUtil.IS_JDK8) {
|
||||
V value = map.get(key);
|
||||
if (null == value) {
|
||||
map.putIfAbsent(key, mappingFunction.apply(key));
|
||||
value = map.get(key);
|
||||
|
||||
// 判空后调用依旧无法解决死循环问题
|
||||
//value = map.computeIfAbsent(key, mappingFunction);
|
||||
}
|
||||
return value;
|
||||
return computeIfAbsentForJdk8(map, key, mappingFunction);
|
||||
} else {
|
||||
return map.computeIfAbsent(key, mappingFunction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果 key 对应的 value 不存在,则使用获取 mappingFunction 重新计算后的值,并保存为该 key 的 value,否则返回 value。<br>
|
||||
* 解决使用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.
|
||||
*
|
||||
* <p>
|
||||
* 注意此方法只能用于JDK8
|
||||
* </p>
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @param map Map,一般用于线程安全的Map
|
||||
* @param key 键
|
||||
* @param mappingFunction 值计算函数
|
||||
* @return 值
|
||||
* @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 computeIfAbsentForJdk8(final Map<K, V> map, final K key, final Function<? super K, ? extends V> mappingFunction) {
|
||||
V value = map.get(key);
|
||||
if (null == value) {
|
||||
value = mappingFunction.apply(key);
|
||||
final V res = map.putIfAbsent(key, value);
|
||||
if(null != res){
|
||||
// issues#I6RVMY
|
||||
// 如果旧值存在,说明其他线程已经赋值成功,putIfAbsent没有执行,返回旧值
|
||||
return res;
|
||||
}
|
||||
// 如果旧值不存在,说明赋值成功,返回当前值
|
||||
|
||||
// Dubbo的解决方式,判空后调用依旧无法解决死循环问题
|
||||
// 见:Issue2349Test
|
||||
//value = map.computeIfAbsent(key, mappingFunction);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
@ -72,15 +72,7 @@ public class SafeConcurrentHashMap<K, V> extends ConcurrentHashMap<K, V> {
|
||||
@Override
|
||||
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
if (JdkUtil.IS_JDK8) {
|
||||
V value = get(key);
|
||||
if (null == value) {
|
||||
putIfAbsent(key, mappingFunction.apply(key));
|
||||
value = get(key);
|
||||
|
||||
// 判空后调用依旧无法解决死循环问题
|
||||
//value = map.computeIfAbsent(key, mappingFunction);
|
||||
}
|
||||
return value;
|
||||
return MapUtil.computeIfAbsentForJdk8(this, key, mappingFunction);
|
||||
} else {
|
||||
return super.computeIfAbsent(key, mappingFunction);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user