你们可能都听过JDK7中的HashMap在多线程环境下可能形成CPU 100%的现象,这个因为在扩容的时候put时产生了死链,由此会在get时形成了CPU 100%。这个问题在JDK8中的HashMap得到了解决。其实JDK7中的HashMap在多线程环境下不止只有CPU 100%这一共怪异现象,它还可能形成插入的数据丢失,有兴趣的读者能够自行了解下。java
对于HashMap多线程的问题,咱们一般会这么反问:HashMap设计上就不是多线程安全的,何须要去在多线程环境下用呢?的确如此,咱们不会傻到显式的在多线程环境下调用,可是又可能在你所关注的视角范围外是多线程的,其隐式地让HashMap置于多线程环境下了,这个又难以一会儿察觉到。再者,对于HashMap多线程的问题,咱们不少时候推荐使用ConcurrentHashMap来代替HashMap应用于多线程的环境,很不巧的是ConcurrentHashMap也有可能会形成CPU 100%的异常现象。这个怪异现象存在于JDK8的ConcurrentHashMap中,在JDK9中已经获得修复,能够参见:安全
https://bugs.openjdk.java.net/browse/JDK-8062841多线程
什么状况下JDK8的ConcurrentHashMap会出现这个Bug呢?首先咱们来运行一下这段代码:架构
你会惊奇的发现这个程序一直处于Running状态,咱们经过top -Hp [pid]命令查看到其中一个线程的CPU使用率接近100%,参考下图:学习
能够看到pid为31417的东东,咱们再经过jstack -l [pid]命令查看到对应的线程为:.net
注意将nid=0x7ab9的16进制转为10进制就是31417。能够看到问题是发生在了computeIfAbsent方法中,咱们将示例中的程序换成下面这段程序也会一样出现CPU 100%的Bug:线程
问题的关键在于递归使用了computeIfAbsent方法,笔者在stackoverflow上还搜索到了同类型的问题,下面的示例程序中调用fibonacci方法一样也会形成CPU 100%.设计
至于为何会发生这个BUG,答案就在ConcurrentHashMap中的computeIfAbsent方法中,本身去捞吧,嘿嘿。或者等之后的文章。怎么规避这个问题呢?只要不在递归中使用computeIfAbsent方法就好啦,或者降级用可爱的分段锁,或者升级JDK9。3d
欢迎工做一到八年的Java工程师朋友们加入Java高级交流:787707172blog
本群提供免费的学习指导 架构资料 以及免费的解答
不懂得问题均可以在本群提出来 以后还会有直播平台和讲师直接交流噢