多线程 HashMap 死循环 问题解析

多线程 HashMap 死循环 问题解析

源码

resize

    void resize(int newCapacity)  
    {  
        Entry[] oldTable = table;  
        int oldCapacity = oldTable.length;  
        ......  
        //创建一个新的Hash Table  
        Entry[] newTable = new Entry[newCapacity];  
        //将Old Hash Table上的数据迁移到New Hash Table上  
        transfer(newTable);  
        table = newTable;  
        threshold = (int)(newCapacity * loadFactor);  
    }  
复制代码

迁移

    void transfer(Entry[] newTable)  
    {  
        Entry[] src = table;  
        int newCapacity = newTable.length;  
        //下面这段代码的意思是:  
        //  从OldTable里摘一个元素出来,然后放到NewTable中  
        for (int j = 0; j < src.length; j++) {  
            Entry<K,V> e = src[j];  
            if (e != null) {  
                src[j] = null;  
                do {  
                    Entry<K,V> next = e.next;  
                    int i = indexFor(e.hash, newCapacity);  
                    e.next = newTable[i];  
                    newTable[i] = e;  
                    e = next;  
                } while (e != null);  
            }  
        }  
    }  
复制代码

我们可以知道newTable 是新创建的 是线程私有的, 因为 线程1 获取 e 和next 之后 线程2 插入执行了,执行完是 倒序的链条, 线程1 再插入 e 和next的 方向 与 线程2执行之后的 方向不对应 导致 循环两次之后 出现问题,会丢数据 ,问题主要集中在最后一次(第3此)执行之后 e,next 均指向null 循环结束

丢数据的问题比较大,

两个线程 ,

do {  
    Entry<K,V> next = e.next; // <--假设线程一执行到这里就被调度挂起了  
    int i = indexFor(e.hash, newCapacity);  
    e.next = newTable[i];  
    newTable[i] = e;  
    e = next;  
} while (e != null); 
复制代码

原来:3 -> 7 -> 6 -> 5( 数据5 resize的时候 分到了其他数组 这里不管它 )

线程1 在 上图位置 卡住, e1 指向3 和 next1 指向 7

线程2 执行

执行后结果为 6 -> 7 -> 3 -> null

ps:没什么画图工具 手画了一下

参考文章:http://blog.csdn.net/xiaohui127/article/details/11928865

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值