第一點多執行緒同時put的時候
在某一時刻同時操作hashmap並執行put操作,而有大於兩個key的hash值相同,如圖中a1、a2,這個時候需要解決碰撞衝突,而解決衝突的辦法上面已經說過,對於鍊錶的結構在這裡不再贅述,暫且不討論是從鍊錶頭部插入還是從尾部初入,這個時候兩個執行緒如果恰好都取到了對應位置的頭結點e1,而最終的結果可想而知,a1、a2兩個資料中勢必會有乙個會丟失
第二點大小resize的時候
擴容方法也不是同步的,通過**我們知道在擴容過程中,會新生成乙個新的容量的陣列,然後對原陣列的所有鍵值對重新進行計算和寫入新的陣列,之後指向新生成的陣列。
當多個執行緒同時檢測到總數量超過門限值的時候就會同時呼叫resize操作,各自生成新的陣列並rehash後賦給該map底層的陣列table,結果最終只有最後乙個執行緒生成的新陣列被賦給table變數,其他執行緒的均會丟失。而且當某些執行緒已經完成賦值而其他執行緒剛開始的時候,就會用已經被賦值的table作為原始陣列,這樣也會有問題。
HashMap為什麼是執行緒不安全的
hashmap底層是乙個entry陣列,當發生hash衝突的時候,hashmap是採用鍊錶的方式來解決的,在對應的陣列位置存放鍊錶的頭結點。對鍊錶而言,新加入的節點會從頭結點加入。我們來分析一下多執行緒訪問 1.在hashmap做put操作的時候會呼叫下面方法 新增entry。將 key value...
HashMap為什麼是執行緒不安全的
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 此函式tra...
53 HashMap 為什麼執行緒不安全?
小景哥哥部落格 jdk7 存在死迴圈和資料丟失問題。資料丟失 死迴圈 擴容時resize呼叫transfer使用頭插法遷移元素,雖然 newtable 是區域性變數,但原先 table 中的 entry 鍊錶是共享的,問題根源是 entry 的 next 指標併發修改,某執行緒還沒有將 table ...