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

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。

    原文作者:impbb
    原文地址: https://blog.csdn.net/qq_27007251/article/details/71403647
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞