• 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插入的数据给覆盖,发生线程不安全

  • 相关阅读:
    DML
    DDL
    SQL的分类
    SQL语句的规范
    sql的演示
    运算符
    导入导出数据
    mysql的数据类型
    python+selenium2自动化---复用已有的浏览器
    python+selenium2自动化---通过js脚本给时间控件赋值
  • 原文地址:https://www.cnblogs.com/Jomini/p/13906691.html
Copyright © 2020-2023  润新知