一、问题描述
经常有些面试官会问,是否了解过 HashMap 在多线程环境下使用时可能会发生死循环,导致服务器 cpu 100% 的线上故障?
关于这个问题,很多年前,在淘宝内网里就有很多的程序员发过这种帖子说一个CPU 被100%了,原因竟是多线程环境下使用 HashMap 造成的死循环,并且这个事发生了很多次。
虽然 Java 官方明确表示,在多线程环境下不推荐使用 HashMap,但是对于这种问题,小编其实也比较意外,如果不是深入的去了解 HashMap,都不知道有这样的问题。
为什么会产生死循环呢?下面我们来还原一下问题的经过。
二、问题重现
在之前的集合系列文章中,我们了解到 HashMap 是一个哈希数组 + 链表的数据结构,在实际的程序开发中,我们经常会使用到 HashMap,如果对 HashMap 不是很了解,大家可以看小编之前写的**《深入浅出分析 HashMap 》**一文。
HashMap 是一个非线程安全的集合操作类,如果我们的程序操作是单线程的,那么一切都没问题。当我们的程序是多线程操作 HashMap 类时,那么问题就来了,我们一起来复现一下。
测试代码,如下:
使用了4个线程来向 HashMap 中添加元素,可能一次运行不一定有效果,可以反复运行几次!
控制台输出结果:
可以清晰的看到,在遍历 map 的内容时,已经死循环了!
再来看看,活动监视器,结果如下:
cpu 的使用率,直接接近 200%!
接下来我们去查看下 java 中刚刚运行的 HashThreadTest 类堆栈情况:
可以看到,HashMap 的扩容操作导致了死循环!