不止JDK7的HashMap,JDK8的ConcurrentHashMap也会造成CPU 100%

大家可能都听过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呢?首先我们来运行一下这段代码:

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

你会惊奇的发现这个程序一直处于Running状态,我们通过top -Hp [pid]命令查看到其中一个线程的CPU使用率接近100%,参考下图:


可以看到pid为31417的东东,我们再通过jstack -l [pid]命令查看到对应的线程为:

注意将nid=0x7ab9的16进制转为10进制就是31417。可以看到问题是发生在了computeIfAbsent方法中,我们将示例中的程序换成下面这段程序也会同样出现CPU 100%的Bug:

map.computeIfAbsent("AaAa",(String key) -> {map.put("BBBB", "value");return "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);});
}

至于为什么会发生这个BUG,答案就在ConcurrentHashMap中的computeIfAbsent方法中,自己去捞吧。

怎么规避这个问题呢?

只要不在递归中使用computeIfAbsent方法就好啦,或者降级用可爱的分段锁,或者升级JDK9~

【End】

老王给大家准备一份「Java最常见200+面试题全解析」,助力大家找到更好的工作,这份面试题包含的模块:

  • Java、JVM 最常见面试题解析

  • Spring、Spring MVC、MyBatis、Hibernate 面试题解析

  • MySQL、Redis 面试题解析

  • RabbitMQ、Kafka、Zookeeper 面试解析

  • 微服务 Spring Boot、Spring Cloud 面试解析

扫描下面二维码付费阅读

关注下方二维码,订阅更多精彩内容。

转发朋友圈,是对我最大的支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于发布DIPS的MVC项目的IIS 7.0环境配置的方法

本人技术笨拙&#xff0c;今天在发布DIPS的MVC4.0项目&#xff0c;并部署到IIS上&#xff0c;遇到各种问题。在查询相关资料后&#xff0c;最终得以解决&#xff0c;所以想把这个过程记录下来。 注&#xff1a;DIPS为一种非关系型数据库 首先&#xff0c;需要安装和注册DIPS。注…

Veket PuppyLinux系统装在U盘中

在碎片化或移动式办公的需求前&#xff0c;怎样才能做到只借助别人的硬件&#xff0c;而使用的是自己的操作系统以及保存数据呢&#xff1f;此时你可能会想到将某个Linux的桌面版本推送并存放在U盘中&#xff0c;便于按需进行启动与使用。 Veket是基于Puppy的一个Linux简体中文…

Java调优:Mybaitis的缓存优化

作者&#xff1a;肥朝&#xff0c;来自肥朝&#xff08;ID&#xff1a;feichao_java&#xff09;我们先来看代码这段代码中, Mybatis一共发了两条SQL,这就好像说, Mybatis中没有缓存,然后我们打开Mybatis的文档一看,顿时震惊这难道是骗人的,说好的默认开启缓存呢…..其实不是的…

Shell编程之多命令顺序执行和管道符

1.多命令顺序执行&#xff1a; 打开!命令终端&#xff1a; 2.管道符 打开命令终端&#xff1a;

阿里一面 缓存穿透、缓存击穿、缓存雪崩和热点数据失效问题的解决方案

作者&#xff1a;乔二爷&#xff0c;来自&#xff1a;乔二爷&#xff08;ID&#xff1a;hellozhouq&#xff09;1 前言昨天晚上接到阿里的电面电话&#xff0c;过程中就问到了关于缓存相关的问题。虽然以前接触过&#xff0c;多多少少了解了一些。但是之前自己并没有好好记录这…

Fix chrome 下flash crash的问题

2019独角兽企业重金招聘Python工程师标准>>> 本来好好的&#xff0c;结果不知道为什么&#xff0c;在MAC下使用chrome不断出现flash插件的错误&#xff0c;网上搜了一下&#xff0c;看这里&#xff0c;要把chrome自带的flash插件注释掉。重启chrome好象是没什么问题…

为什么阿里巴巴建议集合初始化时,指定集合容量大小?

集合是Java开发日常开发中经常会使用到的。在之前的一些文章中&#xff0c;我们介绍过一些关于使用集合类应该注意的事项&#xff0c;如《为什么阿里巴巴禁止在 foreach 循环里进行元素的 remove/add 操作》。关于集合类&#xff0c;《阿里巴巴Java开发手册》中其实还有另外一个…

十五、Python操作mysql数据库

利用Navicat Premium 15软件连接mysql数据库&#xff0c;新建testdb数据库&#xff0c;并添加2个表usertest和userinfo。 main.py #!/usr/bin/python3 # -*- coding: utf-8 -*- import reimport pymysql # 导入模块myConn pymysql.connect(host127.0.0.1, # 主机模块port33…

面试必备的分布式事物方案

四月初&#xff0c;去面试了本市的一家之前在做办公室无人货架的公司&#xff0c;虽然他们现在在面临着转型&#xff0c;但是对于我这种想从传统企业往互联网行业走的孩子来说&#xff0c;还是比较有吸引力的。在面试过程中就提到了分布式事物问题。我又一次在没有好好整理的问…

记住:永远不要在MySQL中使用UTF-8

原文地址:https://dwz.cn/QS4wLyjh最近我遇到了一个bug&#xff0c;我试着通过Rails在以“utf8”编码的MariaDB中保存一个UTF-8字符串&#xff0c;然后出现了一个离奇的错误&#xff1a;Incorrect string value: ‘\xF0\x9F\x98\x83 <…’ for column ‘summary’ at row 1我…

面试官:不使用synchronized和lock,如何实现一个线程安全的单例?

单例&#xff0c;大家肯定都不陌生&#xff0c;这是Java中很重要的一个设计模式。稍微了解一点单例的朋友也都知道实现单例是要考虑并发问题的&#xff0c;一般情况下&#xff0c;我们都会使用synchronized来保证线程安全。那么&#xff0c;如果有这样一道面试题&#xff1a;不…

Mac OS X中配置Apache

我使用的Mac OS X版本是10.8.2&#xff0c;Mac自带了Apache环境。 启动Apache设置虚拟主机启动Apache 打开“终端(terminal)”&#xff0c;输入 sudo apachectl -v&#xff0c;&#xff08;可能需要输入机器秘密&#xff09;。如下显示Apache的版本 接着输入 sudo apachectl st…

你真的理解零拷贝了吗?

作者&#xff1a;ksfzhaohui 来源&#xff1a;http://t.cn/ESALgwV前言从字面意思理解就是数据不需要来回的拷贝&#xff0c;大大提升了系统的性能&#xff1b;这个词我们也经常在java nio&#xff0c;netty&#xff0c;kafka&#xff0c;RocketMQ等框架中听到&#xff0c;经常…

一、华为鸿蒙开发HUAWEI DevEco Studio下载、安装与配置

一、HUAWEI DevEco Studio下载 https://developer.harmonyos.com/cn/develop 二、HUAWEI DevEco Studio安装 解压后&#xff0c;双击安装包。 打开启动 DevEco Studio 三、DevEco Studio配置 DevEco Studio开发环境需要依赖于网络环境&#xff0c;需要连接上…

从JDK中,我们能学到哪些设计模式?

作者&#xff1a;肥朝 来自&#xff1a;肥朝&#xff08;ID&#xff1a;feichao_java&#xff09;结构性模式&#xff1a;适配器模式&#xff1a;常用于将一个新接口适配旧接口肥朝小声逼逼&#xff1a;在我们业务代码中经常有新旧接口适配需求&#xff0c;可以采用该模式。桥…

二、华为鸿蒙开发DevEco Studio运行第一个Hello World工程

1.打开DevEco Studio,创建一个Empty Ability(Java)工程,工程类型:Application 2.按照下图,Tools->Device Manager打开设备管理

解析url

2019独角兽企业重金招聘Python工程师标准>>> #include <stdio.h> #include <string.h> #include <stdlib.h>// 解析url&#xff0c;作为示例&#xff0c;很多情况没考虑&#xff0c;比如说user,pass之类的 int parse_url(char *url, char **serve…

面试官:讲一下Jvm中如何判断对象的生死?

但凡问到 JVM&#xff08;Java 虚拟机&#xff09;通常有 99% 的概率一定会问&#xff0c;在 JVM 中如何判断一个对象的生死状态&#xff1f;判断对象的生死状态的算法有以下几个&#xff1a;1、引用计数器算法引用计算器判断对象是否存活的算法是这样的&#xff1a;给每一个对…

三、华为鸿蒙HarmonyOS应用开发HUAWEI DevEco Studio实现页面跳转

在上一节二、华为鸿蒙开发DevEco Studio运行第一个Hello Word工程 基础上进行下面步骤。 在Java UI框架中,提供了两种编写布局的方式:在XML中声明UI布局和在代码中创建布局。这两种方式创建出的布局没有本质差别,为了熟悉两种方式,我们将通过XML的方式编写第一个页面,通过…