• HashMap的死锁 与 ConcurrentHashMap


    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,超过阈值就会去扩容。

  • 相关阅读:
    0317复利计算的回顾与总结
    0518 Scrum 项目 5.0
    0517 Scrum 项目4.0
    0512 Scrum 项目3.0
    实验三 进程调度模拟程序
    0505 Scrum 项目1.0
    0502团队项目 SCRUM团队成立
    0428 团队项目2.0
    0422团队项目
    实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/yufeng218/p/13211236.html
Copyright © 2020-2023  润新知