zoukankan      html  css  js  c++  java
  • HashMap 为什么线程不安全

      Hashmap 在多线程下不安全,但是 在 jdk 1.7 和 jdk 1.8 不安全体现不同。

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

      在jdk1.8中,在多线程环境下,会发生数据覆盖的情况。

    JDK1.7

      HashMap 1.7 多线程下不安全,体现在其扩容的时候。

      当两个线程同时 使用 put() 的时候,触发了扩容操作,扩容后,对应的节点的桶会产生环形链表,并在后续对该节点的轮询操作产生死循环。

      即下面的代码中产生。

    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;
                }
            }
    }

    JDK1.8

      如果没有hash碰撞则会直接插入元素。如果线程A和线程B同时进行put操作,刚好这两条不同的数据hash值一样,并且该位置数据为null,所以这线程A、B都会进入第6行代码中。

      假设一种情况,线程A进入后还未进行数据插入时挂起,而线程B正常执行,从而正常插入数据,然后线程A获取CPU时间片,此时线程A不用再进行hash判断了,问题出现:线程A会把线程B插入的数据给覆盖,发生线程不安全

  • 相关阅读:
    SSM框架使用遇到的问题
    《深入浅出wpf》第四章 x名称空间详解
    《深入浅出wpf》第三章
    《深入浅出wpf》第二章
    《深入浅出wpf》第一章
    《深入浅出wpf》序
    opencv2411配置
    k均值
    qt新建类报无法解析外部符号(link错误)
    fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  • 原文地址:https://www.cnblogs.com/Jomini/p/13906691.html
Copyright © 2011-2022 走看看