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)一直死循环高并发