HashMap死循环的原因分析
2014-09-28 00:00
429 查看
HashMap其实并不是线程安全的,在高并发的情况下,是很可能发生死循环的,由此造成CPU 100%,这是很可怕的,所以在多线程的情况下,用HashMap是很不妥当的行为,应采用线程安全类ConcurrentHashMap进行代替。
HashMap死循环原因
HashMap进行存储时,如果size超过当前最大容量*负载因子时候会发生resize,首先看一下resize原代码
而这段代码中又调用了transfer()方法,而这个方法实现的机制就是将每个链表转化到新链表,并且链表中的位置发生反转,而这在多线程情况下是很容易造成链表回路,从而发生get()死循环,我们看一下他的源代码
HashMap死循环演示
假如有两个线程P1、P2,以及链表 a=》b=》null
1、P1先执行,执行完”Entry<K,V> next = e.next;”代码后发生阻塞,或者其他情况不再执行下去,此时e=a,next=b
2、而P2已经执行完整段代码,于是当前的新链表newTable[i]为b=》a=》null
3、P1又继续执行”Entry<K,V> next = e.next;”之后的代码,则执行完”e=next;”后,newTable[i]为a《=》b,则造成回路,while(e!=null)一直死循环
总结
HashMap并非线程安全,所以在多线程情况下,应该首先考虑用ConcurrentHashMap,避免悲剧的发生
HashMap死循环原因
HashMap进行存储时,如果size超过当前最大容量*负载因子时候会发生resize,首先看一下resize原代码
void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = oldTable.length; if (oldCapacity == MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; return; } Entry[] newTable = new Entry[newCapacity]; transfer(newTable); table = newTable; threshold = (int)(newCapacity * loadFactor); }
而这段代码中又调用了transfer()方法,而这个方法实现的机制就是将每个链表转化到新链表,并且链表中的位置发生反转,而这在多线程情况下是很容易造成链表回路,从而发生get()死循环,我们看一下他的源代码
void transfer(Entry[] newTable) { Entry[] src = table; int newCapacity = newTable.length; for (int j = 0; j < src.length; j++) { Entry<K,V> e = src[j]; if (e != null) { src[j] = null; do { Entry<K,V> next = e.next; int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } while (e != null); } } }
HashMap死循环演示
假如有两个线程P1、P2,以及链表 a=》b=》null
1、P1先执行,执行完”Entry<K,V> next = e.next;”代码后发生阻塞,或者其他情况不再执行下去,此时e=a,next=b
2、而P2已经执行完整段代码,于是当前的新链表newTable[i]为b=》a=》null
3、P1又继续执行”Entry<K,V> next = e.next;”之后的代码,则执行完”e=next;”后,newTable[i]为a《=》b,则造成回路,while(e!=null)一直死循环
总结
HashMap并非线程安全,所以在多线程情况下,应该首先考虑用ConcurrentHashMap,避免悲剧的发生
相关文章推荐
- HashMap多线程引起的死循环的原因分析
- 漫画:高并发下的HashMap引起的链表死循环原因分析
- Java并发容器ConcurrentHashMap原理及HashMap死循环原因的分析
- 分析多线程并发写HashMap线程被hang住的原因
- 分析多线程并发写HashMap线程被hang住的原因
- HashMap在并发环境下的死循环分析
- 推荐:并发情况下:Java HashMap 形成死循环的原因
- HashMap 多线程下死循环分析及JDK8修复
- hashmap死循环原因总结
- Android Camera开发:扫描二维码,周期性循环自动聚焦auto focus挂掉原因分析(preview is not enabled)
- Android Camera开发:扫描二维码,周期性循环自动聚焦auto focus挂掉原因分析(preview is not enabled)
- 性能分析5~top命令、jps命令、jstack命令:分析多线程下HashMap卡死原因分析
- 分析多线程并发写HashMap线程被hang住的原因
- HashMap多线程下发生死循环的原因
- HashMap 死循环 CPU100%的问题分析
- HashMap死循环问题分析
- HashMap死循环问题分析
- 循环List删除元素抛ConcurrentModificationException异常原因分析
- 分析多线程并发写HashMap线程被hang住的原因
- Android Camera开发:扫描二维码,周期性循环自动聚焦auto focus挂掉原因分析(preview is not enabled)