1. 程式人生 > >HashMap執行緒不安全相關問題

HashMap執行緒不安全相關問題

本文主要從兩個方面探討:
1、為什麼HashMap是執行緒不安全的?
2、具體體現在哪些方面?
答:對於JDK1.7和JDK1.8的HashMap中迭代器的fail-fast策略導致了併發不安全,即如果在使用迭代器的過程中有其他執行緒修改了HashMap就會丟擲ConcurrentModificationException異常(fail-fast策略)
對於JDK1.7的HashMap併發put操作觸發擴容導致潛在可能的死迴圈現象,雜湊衝突的連結串列結構在擴容前後會進行一次逆向首尾對調操作;
而JDK1.8的HashMap併發put操作不會導致潛在的死迴圈,擴容前後連結串列順序性不變。

JDK1.7擴容的核心程式碼如下:

void transfer(HashMapEntry[] newTable){
    //擴容新陣列的容量
    int newCapacity = newTable.length;
    //遍歷舊陣列index元素
    for(HashMapEntry<K,V> e : table){
        while(null!=e){
            HashMapEntry<K,V> next = e.next;
            int i = indexFor(e.hash,newCapacity);
            e.next
= newTable[i]; } } } static int indexFor(int h, int length) { return h & (length-1); }

在 JDK1.7 中併發擴容操作可能會導致雜湊碰撞的連結串列結構為迴圈連結串列,從而導致在後續 put、get 操作時發生死迴圈。而對於 JDK1.8 中擴容連結串列的順序是不會發生逆向的,所以自然怎麼遍歷都不會出現迴圈連結串列的情況,故 JDK1.8 中不會出現併發迴圈連結串列,但由於 JDK1.7 與 JDK1.8 中都是無鎖保護的,所以依然是併發不安全的。

笑話:
我小時候以為,早睡早起身體好,是一句口號。

   長大後才明白,是三個願望……