jdk1.8 hashmap多线程put不会造成死循环

xiaoxiao2021-02-28  77

hashmap多线程操作会造成链表的循环,这个已经被各种博客的讲烂了。大家都知道是put过程中的resize方法在调用transfer方法的时候导致的死锁,故在此不详述。

今天在看《java高并发程序设计》的时候,书中提到“但是这个(hashmap)死循环的问题在jdk8中已经不存在了。由于jdk8对hashmap的内部上线了大规模的调整,因此规避了这个问题”

那么问题来了- -。jdk8是如何规避这个问题的呢,百度无果,只好自己打开源码看看了。比如知名博客《Java8系列之重新认识HashMap》,在讲述resize的时候还是用了jdk7的代码。。。

打开源码 搜索transfer。。。我的天 居然没有。。。

那搜索resize吧。找到核心代码如下(忽略红黑树部分,仅考虑链表部分)

// preserve order Node loHead = null, loTail = null; Node hiHead = null, hiTail = null; Node next; //处理某个hash桶部分 do { next = e.next; {//确定在newTable中的位置 if (loTail == null) loHead = e; else loTail.next = e; loTail = e; } else { if (hiTail == null) hiHead = e; else hiTail.next = e; hiTail = e; } } while ((e = next) != null);

声明两对指针,维护两个连链表

依次在末端添加新的元素。(在多线程操作的情况下,无非是第二个线程重复第一个线程一模一样的操作)

的确没想到这么简单。。。

总结。1.8中hashmap的确不会因为多线程put导致死循环,但是依然有其他的弊端,比如数据丢失等等。因此多线程情况下还是建议使用concurrenthashmap。

转载请注明原文地址: https://www.6miu.com/read-94878.html

最新回复(0)