zoukankan      html  css  js  c++  java
  • resize导致死循环的问题

    多线程扩容:
    这里我们先把核心代码搬出来, 方便查看
     
    while(null != e) {
        Entry<K,V> next = e.next; //第一行
        int i = indexFor(e.hash, newCapacity); //第二行
        e.next = newTable[i]; //第三行
        newTable[i] = e; //第四行
        e = next; //第五行
    }
     
    去掉了一些冗余的代码, 层次结构更加清晰了。
    第一行:记录odl hash表中e.next
    第二行:rehash计算出数组的位置(hash表中桶的位置)
    第三行:e要插入链表的头部, 所以要先将e.next指向new hash表中的第一个元素
    第四行:将e放入到new hash表的头部
    第五行: 转移e到下一个节点, 继续循环下去
     
    核心代码如上所说, 下面就是多线程同时put的情况了, 然后同时进入transfer方法中:

    假设这里有两个线程同时执行了put()操作,并进入了transfer()环节

    while(null != e) {
        Entry<K,V> next = e.next; //线程1执行到这里被调度挂起了
        e.next = newTable[i];
        newTable[i] = e;
        e = next;
    }

    那么现在的状态为:

    从上面的图我们可以看到,因为线程1的 e 指向了 key(3),而 next 指向了 key(7),在线程2 rehash 后,就指向了线程2 rehash 后的链表。

    然后线程1被唤醒了:

    1. 执行e.next = newTable[i],于是 key(3)的 next 指向了线程1的新 Hash 表,因为新 Hash 表为空,所以e.next = null
    2. 执行newTable[i] = e,所以线程1的新 Hash 表第一个元素指向了线程2新 Hash 表的 key(3)。好了,e 处理完毕。
    3. 执行e = next,将 e 指向 next,所以新的 e 是 key(7)

    然后该执行 key(3)的 next 节点 key(7)了:

    1. 现在的 e 节点是 key(7),首先执行Entry<K,V> next = e.next,那么 next 就是 key(3)了
    2. 执行e.next = newTable[i],于是key(7) 的 next 就成了 key(3)
    3. 执行newTable[i] = e,那么线程1的新 Hash 表第一个元素变成了 key(7)
    4. 执行e = next,将 e 指向 next,所以新的 e 是 key(3)

    这时候的状态图为:

    然后又该执行 key(7)的 next 节点 key(3)了:

    1. 现在的 e 节点是 key(3),首先执行Entry<K,V> next = e.next,那么 next 就是 null
    2. 执行e.next = newTable[i],于是key(3) 的 next 就成了 key(7)
    3. 执行newTable[i] = e,那么线程1的新 Hash 表第一个元素变成了 key(3)
    4. 执行e = next,将 e 指向 next,所以新的 e 是 key(7)

    这时候的状态如图所示:

     
    很明显,环形链表出现了!!当然,现在还没有事情,因为下一个节点是 null,所以transfer()就完成了,等put()的其余过程搞定后,HashMap 的底层实现就是线程1的新 Hash 表了。
  • 相关阅读:
    C# 學習使用StatusStrip
    初學C#打印
    C# 學習使用ErrorProvider
    C# 字符串中增、刪、替換字符學習
    mos开发系列教程八:页面代码研究地图控件页面结构
    MapGuide open source开发系列教程五: 屏幕坐标与地图坐标(问题)已修改
    ajax学习笔记一:动态更改div位置
    mos开发系列教七:框架分析
    mos开发系列教程十:说明
    MapGuide open source开发系列教程六: 地图状态与事件(含问题)
  • 原文地址:https://www.cnblogs.com/xxxuwentao/p/10151616.html
Copyright © 2011-2022 走看看