- jdk1.7中HashMap的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;
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;
}
}
}
此函数transfer是在检查到数组需要扩容后,把原先table里的数据重新计算下标后放到newtable里并且覆盖老的数组元素的过程,在jdk1.7中由于采用的是头插法的倒序排列,所以很容易形成环型链表的死循环和数据丢失的情况,而在jdk1.8中由于采用的是尾插法,所以避免了出现死循环的现象。
总结:
- 首先HashMap是线程不安全的,其主要体现:
#1.在jdk1.7中,在多线程环境下,扩容时会造成环形链或数据丢失。
#2.在jdk1.8中,在多线程环境下,会发生数据覆盖的情况。
参考文章:https://www.cnblogs.com/developer_chan/p/10450908.html
https://www.jianshu.com/p/e2f75c8cce01