首页 > 其他 > 详细

HashMap的死锁 与 ConcurrentHashMap

时间:2020-06-30 09:04:33      阅读:73      评论:0      收藏:0      [点我收藏+]

HashMap

Java7,HashMap 会产生死锁;  数据模型:数组 + 链表

Java8,HashMap 不会产生死锁,同时put有可能会产生数据丢失的情况;数据模型:数组 + 链表 + 红黑树

JAVA7 HashMap死锁的原因:hashMap在多线程的场景下,扩容期间存在节点位置互换指针引用,有可能导致死环;

扩容的阈值:threshold = 16 * 0.75,超过阈值就会去扩容。

java7 的 HashMap 的 resize() 方法:

void resize(int newCapacity) {   //传入新的容量
    Entry[] oldTable = table;    //引用扩容前的Entry数组
    int oldCapacity = oldTable.length;         
    if (oldCapacity == MAXIMUM_CAPACITY) {  //扩容前的数组大小如果已经达到最大(2^30)了
        threshold = Integer.MAX_VALUE; //修改阈值为int的最大值(2^31-1),这样以后就不会扩容了
        return;
    }
 
    Entry[] newTable = new Entry[newCapacity];  //初始化一个新的Entry数组
    transfer(newTable);                         //!!将数据转移到新的Entry数组里
    table = newTable;                           //HashMap的table属性引用新的Entry数组
    threshold = (int)(newCapacity * loadFactor);//修改阈值
}

transfer方法:

void transfer(Entry[] newTable) {
     Entry[] src = table;                   //src引用了旧的Entry数组
     int newCapacity = newTable.length;
     for (int j = 0; j < src.length; j++) { //遍历旧的Entry数组
         Entry<K,V> e = src[j];             //取得旧Entry数组的每个元素
         if (e != null) {
             src[j] = null;//释放旧Entry数组的对象引用(for循环后,旧的Entry数组不再引用任何对象)
             do {
                 Entry<K,V> next = e.next;
                 int i = indexFor(e.hash, newCapacity); //!!重新计算每个元素在数组中的位置
                 e.next = newTable[i]; //标记[1]
                 newTable[i] = e;      //将元素放在数组上
                 e = next;             //访问下一个Entry链上的元素
             } while (e != null);
         }
     }
}

  

ConcurrentHashMap

Java7, Segment 继承 ReentrantLock

技术分享图片

 

 

 

 Java8,synchronized加锁,使用 CAS

 技术分享图片

 

 

 

 

 

 

Java1.7 HashMap死锁的原因:hashMap在多线程的场景下,扩容期间存在节点位置互换指针引用,有可能导致死环;

扩容的阈值:threshold = 16 * 0.75,超过阈值就会去扩容。

HashMap的死锁 与 ConcurrentHashMap

原文:https://www.cnblogs.com/yufeng218/p/13211236.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!