我是靠谱客的博主 大气犀牛,最近开发中收集的这篇文章主要介绍concurrentHashmap 中 computerIfAbsent 方法的bug,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1 为了保证原子性,对相同 key 进行修改时,可能造成线程阻塞。

(详细参见:MyBatis 3.5.X 在 JDK8 中的性能问题)

The entire method invocation is performed atomically, so the function is applied at most once per key. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this map.

[JDK-8161372] ConcurrentHashMap.computeIfAbsent(k,f) locks bin when k present

官方在 JDK9 中修复了这个问题。

影响案例:MyBatis DefaultReflectorFactory.java 线程阻塞

public Reflector findForClass(Class<?> type) {
  if (classCacheEnabled) {
    // synchronized (type) removed see issue #461
    return reflectorMap.computeIfAbsent(type, Reflector::new);
    } else {
    return new Reflector(type);
    }
}

解决:

MyBatis 3.5.X 在缓存反射对象用到的 computerIfAbsent 方法在 JDK8 中性能不理想。需要升级 jdk9 及以上版本解决这个问题。对于 MyBatis 本身,没有针对 JDK8 中的 computerIfAbsent 性能问题进行特殊处理,所以升级 MyBatis 版本也不能解决问题。

但可以降级(在 MyBatis 3.4.X 中,还没有引入这个函数,所以理论上可以规避这个问题。

MyBatis 会在 3.5.7 版本中合入这个 PR( MyBatis 官方对 computerIfAbsent 进行了一层封装,如果 value 已存在,则直接 return,这样操作相同 key 的线程阻塞问题就被绕过去了。)。

 

2 JDK8的ConcurrentHashMap也会造成CPU 100%

参见:https://blog.csdn.net/u013256816/article/details/84917112

Map<String, String> map = new ConcurrentHashMap<>();
map.computeIfAbsent("AaAa",
        key -> map.computeIfAbsent("BBBB", key2 -> "value"));

问题的关键在于递归使用了computeIfAbsent方法,笔者在stackoverflow上还搜索到了同类型的问题,下面的示例程序中调用fibonacci方法同样也会造成CPU 100%.

static Map<Integer, Integer> concurrentMap = new ConcurrentHashMap<>();
public static void main(String[] args) {
System.out.println("Fibonacci result for 20 is" + fibonacci(20));
}
static int fibonacci(int i) {
if (i == 0)
return i;
if (i == 1)
return 1;
return concurrentMap.computeIfAbsent(i, (key) -> {
System.out.println("Value is " + key);
return fibonacci(i - 2) + fibonacci(i - 1);
});
}

怎么规避这个问题呢?只要不在递归中使用computeIfAbsent方法就好啦,或者降级用可爱的分段锁,或者升级JDK9~

最后

以上就是大气犀牛为你收集整理的concurrentHashmap 中 computerIfAbsent 方法的bug的全部内容,希望文章能够帮你解决concurrentHashmap 中 computerIfAbsent 方法的bug所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部