zoukankan      html  css  js  c++  java
  • 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,超过阈值就会去扩容。

  • 相关阅读:
    【转载】震惊了!原来这才是kafka!
    Django model层之执行原始SQL查询
    Django model 层之聚合查询总结
    Django 不通过外键实现多表关联查询
    Django model 层之Making Query总结
    Python 基于Python生成短8位唯一id解决方案
    Python shortuuid生成库学习小结
    Django model 层之Models与Mysql数据库小结
    Django Template层之自定义tag
    Django 通过自定义context_processors实现自定义tag
  • 原文地址:https://www.cnblogs.com/yufeng218/p/13211236.html
Copyright © 2011-2022 走看看