前言
HashMap并发情况下的死循环问题在jdk 1.7及之前版本存在的,jdk 1.8 通过增加loHead和loTail进行了修复,虽然进行了修复,但是如果涉及到并发情况下,一般建议使用CurrentHashMap替代HashMap来确保不会出现线程安全问题。
在jdk 1.7及之前 HashMap在并发情况下产生的循环问题,该循环问题将致使服务器的cpu飙升至100%,为了解答这个疑惑,那么今天就来了解一下线程不安全的HashMap在高并发的情况下是如何造成死循环的,要探究hashmap死循环的原因那就要从hashmap的源码开始进行分析,这样才能从根本上对hashmap进行理解。 在分析之前我们要知道在jdk 1.7版本及之前HashMap采用的是数组 + 链表的数据结构,而在jdk 1.8则是采用数组 + 链表 + 红黑树的数据结构以进一步降低hash冲突后带来的查询损耗。
正文
首先hashmap进行元素的插入这里会调用put方法
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);//分配数组空间
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);//对key的hashcode进一步计算,确保散列均匀
int i = indexFor(hash, table.length);//获取在table中的实际位置
for (Entry<K,V> e = table[i]; e != null; e = e.next) {...}
modCount++;//保证并发访问时,若HashMap内部结构发生变化,快速响应失败
//重点关注这个addEntry增加元素的方法
addEntry(hash, key, value, i);