jdk1.7中hashmap的transfer函式如下:
void transfer(entry newtable, boolean rehash)
int i = indexfor(e.hash, newcapacity);
e.next = newtable[i];
newtable[i] = e;
e = next;}}
}
此函式transfer是在檢查到陣列需要擴容後,把原先table裡的資料重新計算下標後放到newtable裡並且覆蓋老的陣列元素的過程,在jdk1.7中由於採用的是頭插法的倒序排列,所以很容易形成環型鍊錶的死迴圈和資料丟失的情況,而在jdk1.8中由於採用的是尾插法,所以避免了出現死迴圈的現象。
首先hashmap是執行緒不安全的,其主要體現:
#1.在jdk1.7中,在多執行緒環境下,擴容時會造成環形鏈或資料丟失。
#2.在jdk1.8中,在多執行緒環境下,會發生資料覆蓋的情況。
參考文章:
HashMap為什麼是執行緒不安全的
hashmap底層是乙個entry陣列,當發生hash衝突的時候,hashmap是採用鍊錶的方式來解決的,在對應的陣列位置存放鍊錶的頭結點。對鍊錶而言,新加入的節點會從頭結點加入。我們來分析一下多執行緒訪問 1.在hashmap做put操作的時候會呼叫下面方法 新增entry。將 key value...
hashmap為什麼不安全
第一點多執行緒同時put的時候 在某一時刻同時操作hashmap並執行put操作,而有大於兩個key的hash值相同,如圖中a1 a2,這個時候需要解決碰撞衝突,而解決衝突的辦法上面已經說過,對於鍊錶的結構在這裡不再贅述,暫且不討論是從鍊錶頭部插入還是從尾部初入,這個時候兩個執行緒如果恰好都取到了對...
53 HashMap 為什麼執行緒不安全?
小景哥哥部落格 jdk7 存在死迴圈和資料丟失問題。資料丟失 死迴圈 擴容時resize呼叫transfer使用頭插法遷移元素,雖然 newtable 是區域性變數,但原先 table 中的 entry 鍊錶是共享的,問題根源是 entry 的 next 指標併發修改,某執行緒還沒有將 table ...