HashMap事實上並不是線程安全的,在高併發的狀況下,是很是可能發生死循環的,由此形成CPU 100%,這是很是可怕的。因此在多線程的狀況下,用HashMap是很是不穩當的行爲,應採用線程安全類ConcurrentHashMap進行取代。java
HashMap進行存儲時,假設size超過當前最大容量*負載因子時候會發生resize。首先看一下resize原代碼安全
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); table = newTable; threshold = (int)(newCapacity * loadFactor); }
void transfer(Entry[] newTable) { Entry[] src = table; int newCapacity = newTable.length; for (int j = 0; j < src.length; j++) { Entry<K,V> e = src[j]; if (e != null) { src[j] = null; do { Entry<K,V> next = e.next; int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } while (e != null); } } }
一、P1先運行,運行完"Entry<K,V> next = e.next;"代碼後發生堵塞,或者其它狀況再也不運行下去,此時e=a。next=b多線程
二、而P2已經運行完整段代碼,因而當前的新鏈表newTable[i]爲b=》a=》null併發
三、P1又繼續運行"Entry<K,V> next = e.next;"以後的代碼,則運行完"e=next;"後,newTable[i]爲a《=》b。則形成迴路,while(e!=null)一直死循環高併發