hashMap擴容時應(yīng)該注意這些死循環(huán)問題
hashMap死循環(huán)
1.原因: jdk1.7時使用頭插入法 ,1.8之后改成了尾插入法解決了這個問題
HashMap死循環(huán)問題圖解
在HashMap的數(shù)組真實長度達到閾值后,會調(diào)用擴容方法:
void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = oldTable.length; if (oldCapacity == MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; return; } Entry[] newTable = new Entry[newCapacity]; transfer(newTable, initHashSeedAsNeeded(newCapacity)); table = newTable; threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1); }
這里可以看到如果有兩個線程A和B,那么在調(diào)用transfer方法之前會在各自的線程中創(chuàng)建新的數(shù)組,然后進入到transfer方法中將節(jié)點轉(zhuǎn)移,再看transfer方法:
void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> next = e.next; ------(1) if (rehash) { e.hash = null == e.key ? 0 : hash(e.key); } int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } } }
我在上面的程序中標(biāo)記了一個(1),待會會用到,首先假設(shè)HashMap中的結(jié)構(gòu)是這樣的:
那么線程A如果執(zhí)行到(1)的位置,那么e為節(jié)點5,next為節(jié)點6,這個時候線程B開始運行,在自己的擴容數(shù)組里面運行:
e.next = newTable[i]; newTable[i] = e;
這個時候結(jié)構(gòu)圖:
然后e=next;
在進入循環(huán)執(zhí)行:
e.next = newTable[i]; newTable[i] = e;
這個時候結(jié)構(gòu)為:
然后線程B執(zhí)行完畢。線程A開始從(1)后面繼續(xù)執(zhí)行,這個時候也是先執(zhí)行
e.next = newTable[i]; newTable[i] = e;
然后e=next;這個時候e是節(jié)點6,然后再進入循環(huán),執(zhí)行上面兩行程序后的結(jié)構(gòu)如下:
但是這個時候由于6的next是有值的,是節(jié)點5,所以再執(zhí)行e=next;的時候,e不為空,還會進入一次循環(huán),在執(zhí)行將節(jié)點插入頭部的操作,所以這個時候的結(jié)構(gòu)圖:
可以,看到已經(jīng)成為了環(huán)狀鏈表,當(dāng)執(zhí)行g(shù)et操作的時候就會產(chǎn)生死循環(huán)。
到此這篇關(guān)于hashMap擴容時應(yīng)該注意這些死循環(huán)問題的文章就介紹到這了,更多相關(guān)hashMap擴容內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Spring MVC3返回JSON數(shù)據(jù)中文亂碼問題解決
本篇文章主要介紹了Spring MVC3返回JSON數(shù)據(jù)中文亂碼問題解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01Spring Security其它權(quán)限校驗方式&自定義權(quán)限校驗方式
這篇文章主要介紹了Spring Security其它權(quán)限校驗方式&自定義權(quán)限校驗方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08java servlet手機app訪問接口(三)高德地圖云存儲及檢索
這篇文章主要為大家詳細介紹了java servlet手機app訪問接口(三),高德地圖云存儲及檢索,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12SpringCloud中的OpenFeign調(diào)用解讀
OpenFeign是一個顯示聲明式的WebService客戶端,使用OpenFeign能讓編寫Web Service客戶端更加簡單OpenFeign的設(shè)計宗旨式簡化Java Http客戶端的開發(fā),本文給大家介紹SpringCloud之OpenFeign調(diào)用解讀,感興趣的朋友一起看看吧2023-11-11解決Error:(5, 28) java: 程序包org.apache.ibatis.io
這篇文章主要介紹了解決Error:(5, 28) java: 程序包org.apache.ibatis.io不存在問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05