HashMap在多线程环境下偶然造成InfiniteLoop导致程序宕机
来源:互联网 发布:图片剪切软件下载 编辑:程序博客网 时间:2024/06/07 03:14
在多线程环境下,非线程安全的hashmap可能会造成的问题
package littlehow.map;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.util.HashMap;import java.util.Map;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;/** * HashMapInfiniteLoop hashmap死循环造成的cpu 100% * 有时候,会出现很奇怪的现象,那就是程序运行一段时间会出现宕机,重启之后就没事儿了 * 具体什么原因也很难查找。 * 在高并发环境下,因为hashmap的线程不安全性,可能会引起上述现象 * 现在就看看,这种现象如何发生的 * * @author littlehow * @time 2016-07-11 10:16 */public class HashMapInfiniteLoop { //初始长度为4的hashmap private Map<Integer, String> map = new HashMap<Integer, String>(4); //线程数量 final int count = 200; final CountDownLatch countDownLatch = new CountDownLatch(count); @Before public void init() { //因为hash计算结果类似于mod,所以我们可以事先准备冲突的hash对 //rehash的源码,可以看出当size==threshold也就是4的时候会进行resize, //从而重新分布元素 /** if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); } for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> next = e.next; if (rehash) { e.hash = null == e.key ? 0 : hash(e.key); } int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } } */ // 3 11 7 15 put后这三个都出现了hash冲突,所以结构为 3 -> 11 -> 7 -> 15 的链表 //当再put19时,又出现冲突, 这时候就需要扩容。 // 正常情况形成两个链表 11 -> 3 -> 19 和 15 -> 7 //但是当执行线程以执行到如 Entry<K,V> next = e.next;获取到的next=11时线程被挂起; //线程二来执行成功,线程一继续,e=7,next=15,进行rehash,执行到 //newTable[i] = e = 7; e = next = 15,而线程二已经排好 15 -> 7, //很明显线程一形成的链表为7 -> 15,合并结果就是 15 -> 7 -> 15形成了环形链表 //这时候get(23)就会一直查找下去,因为元素一直拥有next。从而导致 infinite loop //resize后大小为8 map.put(3, "littlehow"); map.put(11, "color wolf"); map.put(7, "black dog"); map.put(15, "blue blood"); } @Test public void conflict() { /** * 想要出现Entry<K,V> next = e.next;之后挂起线程非常困难,在并发量超级大的情况下有可能会出现 * 所以没有出现死循环是最可能的现象,生产环境往往是不可预测的 * 在多线程环境下使用map这样结构的类有两点建议: * 1.使用ConcurrentHashMap * 2.如果确定map元素多少的情况,最好初始化map尽量大,避免rehash */ for (int i = 0; i < count; i ++) { new Thread("thread-" + (i + 1)) { @Override public void run() { map.put(19, "new person"); countDownLatch.countDown(); } }.start(); } try { TimeUnit.SECONDS.sleep(1); countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } @After public void over() { System.out.println("value=" + map.get(23) + " , size=" + map.size()); }}
0 0
- HashMap在多线程环境下偶然造成InfiniteLoop导致程序宕机
- Java之HashMap在多线程情况下导致死循环的问题
- 在并发环境下使用HashMap导致的线程死循环问题
- HashMap 多线程push造成死锁
- Java在并发情况下使用HashMap造成死循环
- 多线程环境下HashMap之死循环
- 一个验证HashMap在多线程环境下线程不安全的例子及dump分析
- JAVA下的多线程程序造成系统时钟变快
- JAVA下的多线程程序造成系统时钟变快
- JAVA下的多线程程序造成系统时钟变快
- HashMap多线程造成了CPU100%,死循环
- HashMap在高并发下导致CPU过高
- 多线程导致程序崩溃
- 多线程下切换输入法导致程序假死的问题
- 1、关于HashMap在多线程下的不安全分析
- 多线程环境下不安全的消息队列存取---线程不同步会造成隐患
- 在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环?
- HashMap在并发环境下的死循环分析
- HttpServlet详解
- 易语言 客户组件post发送数据带所有信息
- 【SSH进阶之路】Struts + Spring + Hibernate 进阶开端(一)
- 309. Best Time to Buy and Sell Stock with Cooldown
- 9、单表数据查询----第2篇
- HashMap在多线程环境下偶然造成InfiniteLoop导致程序宕机
- 【unix网络编程第三版】阅读笔记(四):TCP客户/服务器实例
- Android 隐藏状态栏
- 整数反转算法(php实现)
- java8学习 -- lambda表达式
- c++向量
- nlp_关键词提取总结
- 练习35——分支和函数
- java.lang.UnsatisfiedLinkError: D:\Tomcat\apache-tomcat-7.0.37\bin\tcnative-1.dll: Can't load AMD 64