JavaWeb程序猿阵线联盟-汇总各类技术干货技术干货

HashMap底层详解-003-resize、并发下的安全问题

2017-11-16  本文已影响19人  53b3f4658edc
微信公众号:JavaWeb架构师
微信公众号:JavaWeb架构师
微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师
    /**
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted

    int s = m.size();
    float ft = ((float)s / loadFactor) + 1.0F;
微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师

1.新建Entry,长度是原长度的两倍

2.rehash,遍历原有的数组,把那些元素重新映射到新的数组上(参考咱们前面的公式,length变了,结果自然就变了)。

void transfer(Entry[] newTable, boolean rehash) {
    int newCapacity = newTable.length;
    // 遍历数组
    for (Entry<K,V> e : table) {
        // 遍历数组中的链表
        while(null != e) {
            Entry<K,V> next = e.next;
            if (rehash) {
                e.hash = null == e.key ? 0 : hash(e.key);
            }
            int i = indexFor(e.hash, newCapacity);
            // 头插法
            e.next = newTable[i];
            newTable[i] = e;
            e = next;
        }
    }
}
微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师
  1. 现在有一个HashMap如下,如果再插入一个元素就会进行扩容


    微信公众号:JavaWeb架构师

2.现在有线程A、B同时执行对这个HashMap的元素插入操作


微信公众号:JavaWeb架构师

3.完成插入之后,A、B线程都要对这个HashMap进行扩容


微信公众号:JavaWeb架构师

4.首先线程A执行


微信公众号:JavaWeb架构师

当线程A对原HashMap遍历到了PHP位置的时候,刚刚执行完上面红框部分的代码,这时候:
e = PHP
next = Java
PHP.next = Java
Java.next = null

5.这时候线程A被挂起,线程B完成了所有的操作


微信公众号:JavaWeb架构师

Java.next = PHP
PHP.next = null

6.线程A恢复执行-下标值


微信公众号:JavaWeb架构师

i的值和线程B中PHP链表的下标一样(参数都是一样,结果就是一样的)

7.线程A恢复执行-PHP第一次
当前状态:
e = PHP
next = Java
Java.next = PHP
PHP.next = null


微信公众号:JavaWeb架构师

这时候PHP被放到了线程A的新HashMap中


微信公众号:JavaWeb架构师

现在:
e = Java
next = Java
Java.next = PHP
PHP.next = null

8.线程A恢复执行-Java第一次


微信公众号:JavaWeb架构师

当前状态:
e = Java
next = PHP
Java.next = PHP
PHP.next = null

代码再次执行到了:


微信公众号:JavaWeb架构师

这时候Java被放到了线程A的HashMap的i位置的表头

微信公众号:JavaWeb架构师

现在:
e = PHP
next = PHP
Java.next = PHP
PHP.next = null

9.线程A恢复执行-PHP第二次(出现问题)


微信公众号:JavaWeb架构师

当前状态:
e = PHP
next = null

微信公众号:JavaWeb架构师

当前状态:
PHP.next = Java
Java.next = PHP
e = null


微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师 微信公众号:JavaWeb架构师


其它

完整教程PDF版本下载
上一篇 下一篇

猜你喜欢

热点阅读