HashMap如何导致CPU100%的?

简介: HashMap如何导致CPU100%的?

一、HashMap的数据结构?


JDK7:数组+链表

JDK8:数组+链表+红黑树


1.1 数组的存储特点


20210201094521545.png

查询:连续性,有下标,查询速度快。

插入:后面的节点需要全部移动,时间复杂度高。

删除:节点下标全部需要改变,除了最后一个节点。

如:java中的ArrayList就是数组实现的


1.2 链表的存储特点

20210201094544787.png


删除:迅速,简单。 时间复杂度为O1.

查询:啥时间复杂度为On,需要从头到尾遍历。

如java中的LinkList的数据结构为双向链表。

2021020109494497.png

1.3 哈希算法的底层是是如何实现的?

20210201100747376.png

也叫散列算法,把任意长度的值散列变换成固定的值,通过地址访问,加快访问速度。

碰撞?冲突?如何解决?

加一个指针就好啦!


二、JDK8为何引入红黑树?


想一下,JDK7数组+链表的数据结构,如果出现哈希值全部一样的情况,那么数据结构中就会存在严重的哈希冲突,这个时候数组中只有少数的数组有数据,然而却存在相当大且长的链表,那么查询的速度严重降低!!!!!


20210201104051734.png


阈值为8,超过了8,转化为红黑树。


2.1 红黑树


红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。


2.2 扩展因子0.75


扩展因子也叫加载因子或负载因子是 HashMap 中的一个属性,如下图所示:假如数组的默认长度为 10,扩展因子为 0.5,那么当数组超过 10*0.5=5 个时,HashMap 就会扩容为之前容量的两倍,所以说扩展因子就是用来判定 HashMap 是否满足扩容条件的。


三、HashMap 导致 CPU 100%


HashMap 导致 CPU 100% 的原因就是因为 HashMap 死循环导致的,那 HashMap 是如何造成死循环的?

HashMap 发生死循环的一个重要原因是 JDK 1.7 时链表的插入是首部倒序插入的,而 JDK 1.8 时已经变成了尾部插入,有人把这个死循环的问题反馈给了 Sun 公司,但它们认为这不是一个问题,因为 HashMap 本身就是非线程安全的,如果要在多线程使用建议使用 ConcurrentHashMap 替代 HashMap,但面试中这个问题被问的频率比较高,所以在这里就特殊说明一下。

HashMap 是非线程安全的,以 JDK 1.7 为例,当多线程并发扩容时就会出现环形引用的问题,从而导致死循环的出现,一直死循环就会导致 CPU 运行 100%,所以在多线程使用时,我们需要使用 ConcurrentHashMap 来替代 HashMap

目录
相关文章
|
6月前
HashMap进行put操作时遇到的并发问题
HashMap进行put操作时遇到的并发问题
34 0
|
9月前
|
安全
浅谈HashTable, HashMap, ConcurrentHashMap 之间的区别
浅谈HashTable, HashMap, ConcurrentHashMap 之间的区别
|
存储 安全
线程进阶 --- HashMap、HashTable和ConcurrentHashMap
线程进阶 --- HashMap、HashTable和ConcurrentHashMap
95 0
线程进阶 --- HashMap、HashTable和ConcurrentHashMap
|
存储 安全 C++
【HashMap优化使用】
【HashMap优化使用】
|
算法 Java
20. 你知道为什么HashMap是线程不安全的吗?上
20. 你知道为什么HashMap是线程不安全的吗?上
59 0
20. 你知道为什么HashMap是线程不安全的吗?上
20. 你知道为什么HashMap是线程不安全的吗?下
20. 你知道为什么HashMap是线程不安全的吗?下
84 0
|
算法 Java
都说 HashMap 是线程不安全的,到底体现在哪儿?
都说 HashMap 是线程不安全的,到底体现在哪儿?
都说 HashMap 是线程不安全的,到底体现在哪儿?
|
存储 安全 Java
多线程环境下HashMap导致CPU100%
多线程环境下HashMap导致CPU100%
248 0
多线程环境下HashMap导致CPU100%
|
监控 Java 数据库
一次 HashSet 所引起的并发问题(上)
首先了解下这个应用大概是做什么的。 简单来说就是从 MQ 中取出数据然后丢到后面的业务线程池中做具体的业务处理。 而报警的队列正好就是这个线程池的队列。
|
SQL 缓存 运维
一次 HashSet 所引起的并发问题(下)
首先了解下这个应用大概是做什么的。 简单来说就是从 MQ 中取出数据然后丢到后面的业务线程池中做具体的业务处理。 而报警的队列正好就是这个线程池的队列。