zoukankan      html  css  js  c++  java
  • HashMap总结

    HashMap的结构图(链表离散的数据结构,即数据加单向链表结构)

    归纳

    简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry 对象。

    HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,当需要存储一个 Entry 对象时,

    会根据hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,

    也会根据hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。

    Fail-Fast机制

    我们知道java.util.HashMap不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,这就是所谓fail-fast策略。

    HashMap为什么线程不安全

    表现1:

    多个线程同时操作一个hashmap就可能出现不安全的情况:

    比如A B两个线程(A线程获数据 B线程存数据) 同时操作myHashMap
    1.B线程执行存放数据
    modelHashMap.put("1","2");
    2.A线程执行get获取数据
    modelHashMap.get("1")
    A线程获取的值本来应该是2,但是如果A线程在刚到达获取的动作还没执行的时候,

    线程执行的机会又跳到线程B,此时线程B又对modelHashMap赋值 如:modelHashMap.put("1","3");

    然后线程虚拟机又执行线程A,A取到的值为3,这样map中第一个存放的值 就会丢失。。。。。

    要保证值的准确,就要保证操作的原子性,就是保证A操作从头开始不能被打断。。所有要用同步关键字,

    或者使用java 1.5中的current新包中的ConcurrentHashMap,这是线程安全的,在java最新的并发包中,对之前非线程安全的工具,如hashMap List 都做了同步封转。

    表现2:

    一般我们声明HashMap时,使用的都是默认的构造方法:HashMap<K,V>,看了代码你会发现,它还有其它的构造方法:HashMap(int initialCapacity, float loadFactor),其中参数initialCapacity为初始容量,

    loadFactor为加载因子,而之前我们看到的threshold = (int)(capacity * loadFactor); 如果在默认情况下,一个HashMap的容量为16,加载因子为0.75,那么阀值就是12,所以在往HashMap中put的值到达12时,它将自动扩容两倍,如果两个线程同时遇到HashMap的大小达到12的倍数时,就很有可能会出现在将oldTable转移到newTable的过程中遇到问题,从而导致最终的HashMap的值存储异常。

    表现3:

    构造entry<K,V>单链表时,也会出现不安全的情况。

    个人总结:个人觉得HashMap在并发时可能出现的问题主要是两方面,首先如果多个线程同时使用put方法添加元素,而且假设正好存在两个put的key发生了碰撞(hash值一样),

    那么根据HashMap的实现,这两个key会添加到数组的同一个位置,这样最终就会发生其中一个线程的put的数据被覆盖。第二就是如果多个线程同时检测到元素个数超过数组大小*loadFactor,

    这样就会发生多个线程同时对Node数组进行扩容,都在重新计算元素位置以及复制数据,但是最终只有一个线程扩容后的数组会赋给table,也就是说其他线程的都会丢失,并且各自线程put的数据也丢失。

    解决方案:

    • Hashtable
    • ConcurrentHashMap
    • Synchronized Map

     

  • 相关阅读:
    表连接 索引
    数据库类型
    Java重试机制
    Result Maps collection already contains value for xxxMapper.BaseResultMap错误解决办法
    Lombok插件
    REST以及RESTful
    Dubbo
    【日志】MySQL中有多少种日志
    【缓存池】转-Mysql参数innodb_buffer_pool_size
    【MRR】转-MySQL 的 MRR 优化
  • 原文地址:https://www.cnblogs.com/wchxj/p/8641807.html
Copyright © 2011-2022 走看看