并发下HashMap头插会造成死循环情况说明
說明:
JDK1.8之前HashMap觸發(fā)擴(kuò)容機(jī)制時,會創(chuàng)建新的Entry[ ]數(shù)組,將舊的Entry數(shù)據(jù)進(jìn)行復(fù)制,當(dāng)某個entry上具有鏈?zhǔn)浇Y(jié)構(gòu)時,采用頭插方式進(jìn)行數(shù)據(jù)遷移,即將舊鏈表數(shù)據(jù)從頭部遍歷,每次取到的數(shù)據(jù)插入到新鏈表的頭部。
但并發(fā)下會產(chǎn)生死循環(huán),JDK1.8改用尾插方法。
并發(fā)頭插死循環(huán)問題:
比如有兩個線程同時對該HashMap進(jìn)行rehash,要將鏈表進(jìn)行重新排列
rehash前鏈表結(jié)構(gòu)為:A --> B -->C
線程1進(jìn)行操作:遍歷原鏈表,首先獲得節(jié)點(diǎn)A及A.next = B,操作掛起,線程2進(jìn)入。(線程1僅獲取到了數(shù)據(jù)A及next,并未進(jìn)行其他操作)
線程2進(jìn)行操作:遍歷原鏈表,以頭插方式遍歷執(zhí)行,執(zhí)行完成 B – > A。
線程1繼續(xù)執(zhí)行:遍歷原鏈表,頭插方式執(zhí)行,完成 B – > A,此時線程2數(shù)據(jù)提交,線程1發(fā)現(xiàn) B.next 不為null,繼續(xù)遍歷執(zhí)行,又將B.next = A插入,形成A --> B – > A循環(huán)結(jié)構(gòu)。
JDK1.8尾插為什么會避免這個問題,因?yàn)槲膊迕看尾僮?#xff0c;結(jié)點(diǎn)順序都保持不變,自己畫一下就知道了。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的并发下HashMap头插会造成死循环情况说明的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java异常中受检异常非受检异常与Run
- 下一篇: Java泛型失效的两种情况