HashMap为什么是线程不安全的

北战南征 提交于 2020-02-25 14:51:14
  1. 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中由于采用的是尾插法,所以避免了出现死循环的现象。

总结:

  1. 首先HashMap是线程不安全的,其主要体现:

#1.在jdk1.7中,在多线程环境下,扩容时会造成环形链或数据丢失。

#2.在jdk1.8中,在多线程环境下,会发生数据覆盖的情况。
参考文章:https://www.cnblogs.com/developer_chan/p/10450908.html
https://www.jianshu.com/p/e2f75c8cce01

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!