• 如何在很短的时间内将大量数据插入到ConcurrentHashMap(转)


    将大批量数据保存到map中有两个地方的消耗将会是比较大的:第一个是扩容操作,第二个是锁资源的争夺。第一个扩容的问题,主要还是要通过配置合理的容量大小和扩容因子,尽可能减少扩容事件的发生;第二个锁资源的争夺,在put方法中会使用synchonized对头节点进行加锁,而锁本身也是分等级的,因此我们的主要思路就是尽可能的避免锁等级。所以,针对第二点,我们可以将数据通过通过ConcurrentHashMap的spread方法进行预处理,这样我们可以将存在hash冲突的数据放在一个组里面,每个组都使用单线程进行put操作,这样的话可以保证锁仅停留在偏向锁这个级别,不会升级,从而提升效率。

    其他:

    ConcurrentHashMap 1.7和1.8的区别
    1、整体结构
    1.7:Segment + HashEntry + Unsafe

    1.8: 移除Segment,使锁的粒度更小,Synchronized + CAS + Node + Unsafe

    2、put()
    1.7:先定位Segment,再定位桶,put全程加锁,没有获取锁的线程提前找桶的位置,并最多自旋64次获取锁,超过则挂起。

    1.8:由于移除了Segment,类似HashMap,可以直接定位到桶,拿到first节点后进行判断,1、为空则CAS插入;2、为-1则说明在扩容,则跟着一起扩容;3、else则加锁put(类似1.7)

    3、get()
    基本类似,由于value声明为volatile,保证了修改的可见性,因此不需要加锁。

    4、resize()
    1.7:跟HashMap步骤一样,只不过是搬到单线程中执行,避免了HashMap在1.7中扩容时死循环的问题,保证线程安全。

    1.8:支持并发扩容,HashMap扩容在1.8中由头插改为尾插(为了避免死循环问题),ConcurrentHashmap也是,迁移也是从尾部开始,扩容前在桶的头部放置一个hash值为-1的节点,这样别的线程访问时就能判断是否该桶已经被其他线程处理过了。

    5、size()
    1.7:很经典的思路:计算两次,如果不变则返回计算结果,若不一致,则锁住所有的Segment求和。

    1.8:用baseCount来存储当前的节点个数,这就设计到baseCount并发环境下修改的问题(说实话我没看懂-_-!)。

    JDK1.7中扩容中转移数组transfer()方法源码。

    void transfer(Entry[] newTable, boolean rehash) {
        //新table的容量
        int newCapacity = newTable.length;
        //遍历原table
        for (Entry<K,V> e : table) {
            while(null != e) {
                //保存下一次循环的 Entry<K,V>
                Entry<K,V> next = e.next;
                if (rehash) {
                    //通过e的key值计算e的hash值
                    e.hash = null == e.key ? 0 : hash(e.key);
                }
                //得到e在新table中的插入位置
                int i = indexFor(e.hash, newCapacity);
                //采用链头插入法将e插入i位置,最后得到的链表相对于原table正好是头尾相反的
                e.next = newTable[i];
                newTable[i] = e;
                //下一次循环
                e = next;
            }
        }
    }


    原文链接:https://blog.csdn.net/u013374645/article/details/88700927

  • 相关阅读:
    面试2
    面试总结
    谈谈扫码支付的实现流程
    从产品分类、模块功能和业务流程,了解支付产品服务的设计
    【提现】的业务流程
    APP测试点归纳
    安全测试的思路
    一 大型网站架构演化(大型网站技术架构原理)
    Tomcat服务器原理详解
    Tomcat目录结构详解
  • 原文地址:https://www.cnblogs.com/Esquecer/p/11418350.html
Copyright © 2020-2023  润新知