• Java HashMap


    HashMap:先说HashMap,HashMap是线程不安全的,在并发环境下,可能会形成环状链表(扩容时可能造成,具体原因自行百度google或查看源码分析),
    导致get操作时,cpu空转,所以,在并发环境中使用HashMap是非常危险的.

    HashTable:HashTable和HashMap的实现原理几乎一样,差别无非是1.HashTable不允许key和value为null;2.HashTable是线程安全的
    但是HashTable线程安全的策略实现代价却太大了,简单粗暴,get/put所有相关操作都是synchronized的,
    这相当于给整个哈希表加了一把[大锁],多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞,相当于将所有的操作串行化,在竞争激烈的并发场景中性能就会非常差。
    HashTable[全表锁机制]--性能较差

    ConcurrentHashMap采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组.
    Segment继承了ReentrantLock,所以它就是一种可重入锁(ReentrantLock)。
    在ConcurrentHashMap,一个Segment就是一个子哈希表,Segment里维护了一个HashEntry数组,并发环境下,
    对于不同Segment的数据进行操作是不用考虑锁竞争的。(按默认的ConcurrentLeve为16来讲,理论上就允许16个线程并发执行)


    put的过程很清晰,对当前的table进行无条件自循环直到put成功,可以分成以下六步流程来概述
    1.如果没有初始化就先调用initTable()方法来进行初始化过程
    2.如果没有hash冲突就直接CAS插入
    3.如果还在进行扩容操作就先进行扩容
    4.如果存在hash冲突,就加锁来保证线程安全,这里有两种情况,一种是链表形式就直接遍历到尾端插入,一种是红黑树就按照红黑树结构插入,
    5.最后一个如果该链表的数量大于阈值8,就要先转换成黑红树的结构,break再一次进入循环
    6.如果添加成功就调用addCount()方法统计size,并且检查是否需要扩容


    ConcurrentHashMap的get操作的流程很简单,也很清晰,可以分为三个步骤来描述
    1.计算hash值,定位到该table索引位置,如果是首节点符合就返回
    2.如果遇到扩容的时候,会调用标志正在扩容节点ForwardingNode的find方法,查找该节点,匹配就返回
    3.以上都不符合的话,就往下遍历节点,匹配就返回,否则最后就返回null

  • 相关阅读:
    【Unity3D】使用MD5值,确保本地Sqlite数据库内容没有被篡改
    《Unity3D》通过对象池模式,管理场景中的元素
    NGUI制作 《九宫格》 图片
    NGUI混合FingerGesture《卷二》分离触摸事件
    js的各种获取大小
    sass基础
    js面向对象开发基础
    正则表达式(进阶篇)
    正则表达式(基础篇)
    jquery源码学习(三)—— jquery.prototype主要属性和方法
  • 原文地址:https://www.cnblogs.com/jasonandy/p/9821555.html
Copyright © 2020-2023  润新知