天津网站制作工具,网站设计公司网站设计公司,生意网官网,做女团学什么舞蹈视频网站大家可能都听过JDK7中的HashMap在多线程环境下可能造成CPU 100%的现象#xff0c;这个由于在扩容的时候put时产生了死链#xff0c;由此会在get时造成了CPU 100%。这个问题在JDK8中的HashMap获得了解决。其实JDK7中的HashMap在多线程环境下不止只有CPU 100%这一共怪异现象这个由于在扩容的时候put时产生了死链由此会在get时造成了CPU 100%。这个问题在JDK8中的HashMap获得了解决。其实JDK7中的HashMap在多线程环境下不止只有CPU 100%这一共怪异现象它还可能造成插入的数据丢失有兴趣的读者可以自行了解下。对于HashMap多线程的问题我们通常会这么反问HashMap设计上就不是多线程安全的何必要去在多线程环境下用呢的确如此我们不会傻到显式的在多线程环境下调用但是又可能在你所关注的视角范围外是多线程的其隐式地让HashMap置于多线程环境下了这个又难以一下子察觉到。再者对于HashMap多线程的问题我们很多时候推荐使用ConcurrentHashMap来代替HashMap应用于多线程的环境很不巧的是ConcurrentHashMap也有可能会造成CPU 100%的异常现象。这个怪异现象存在于JDK8的ConcurrentHashMap中在JDK9中已经得到修复可以参见https://bugs.openjdk.java.net/browse/JDK-8062841什么情况下JDK8的ConcurrentHashMap会出现这个Bug呢首先我们来运行一下这段代码MapString, String map new ConcurrentHashMap();
map.computeIfAbsent(AaAa,key - map.computeIfAbsent(BBBB, key2 - value));
你会惊奇的发现这个程序一直处于Running状态我们通过top -Hp [pid]命令查看到其中一个线程的CPU使用率接近100%参考下图可以看到pid为31417的东东我们再通过jstack -l [pid]命令查看到对应的线程为注意将nid0x7ab9的16进制转为10进制就是31417。可以看到问题是发生在了computeIfAbsent方法中我们将示例中的程序换成下面这段程序也会同样出现CPU 100%的Bugmap.computeIfAbsent(AaAa,(String key) - {map.put(BBBB, value);return value;});
问题的关键在于递归使用了computeIfAbsent方法笔者在stackoverflow上还搜索到了同类型的问题下面的示例程序中调用fibonacci方法同样也会造成CPU 100%.static MapInteger, 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);});
}
至于为什么会发生这个BUG答案就在ConcurrentHashMap中的computeIfAbsent方法中自己去捞吧。怎么规避这个问题呢只要不在递归中使用computeIfAbsent方法就好啦或者降级用可爱的分段锁或者升级JDK9~【End】老王给大家准备一份「Java最常见200面试题全解析」助力大家找到更好的工作这份面试题包含的模块Java、JVM 最常见面试题解析Spring、Spring MVC、MyBatis、Hibernate 面试题解析MySQL、Redis 面试题解析RabbitMQ、Kafka、Zookeeper 面试解析微服务 Spring Boot、Spring Cloud 面试解析扫描下面二维码付费阅读关注下方二维码订阅更多精彩内容。转发朋友圈是对我最大的支持。