赞
踩
HashMap死循环问题是JDK1.7之前存在问题,主要源于HashMap的自身的工作机制和并发处理导致的问题,而对于JDK1.8后,官方就彻底解决了这个问题,对于死循环问题,我们首先了解一下HashMap数据插入原理
在Java的HashMap中,put()操作采用的是“头插法”,也就是把新元素插入到链表头部。如有相同的key值插入,会覆盖旧元素。如果新元素的key值在HashMap中不存在,则会新建一个节点并放在链表头部。如果此时桶(bucket)数组中对应位置已经有了元素,那么新插入的元素会作为该元素的前驱。
多线程下多个线程同时在扩容临界点进行插入操作,同时开始进行扩容
多个线程同时进行扩容,扩容前首先需要获取结尾元素的下一个节点信息,以便使用头插法进行扩容。然后有部分线程时间片用完,在获取节点信息后就就行休眠了,还没开始进行头插扩容。有部分线程直接进行扩容操作,在扩容操作过程种的节点结构重组消息休眠线程不知道。
第二阶段进行扩容操作后,节点结构重组后,休眠的线程拿着旧的节点消息进行二次头插,致使死循环
1.使用线程安全的ConcurrentHashMap替代HashMap,推荐
2.使用线程安全的容器Hashtable替代,性能低,不建议
3.使用synchronized或Lock加锁,会影响性能,不建议
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。