next tab

ConcurrentHashMap原理分析和总结(JDK1.8)

有些话、适合烂在心里 提交于 2020-10-04 22:50:08
HashMap的线程安全版本,可以用来替换HashTable。在hash碰撞过多的情况下会将链表转化成红黑树。1.8版本的ConcurrentHashMap的实现与1.7版本有很大的差别,放弃了段锁的概念,借鉴了HashMap的数据结构:数组+链表+红黑树。ConcurrentHashMap不接受nullkey和nullvalue。 数据结构: 数组+链表+红黑树 并发原理: cas乐观锁+synchronized锁 加锁对象: 数组每个位置的头节点 方法分析: put方法: 先根据key的hash值定位桶位置,然后cas操作获取该位置头节点,接着使用synchronized锁锁住头节点,遍历该位置的链表或者红黑树进行插入操作。 稍微具体一点: 1.根据key的hash值定位到桶位置 2.判断if(table==null),先初始化table。 3.判断if(table[i]==null),cas添加元素。成功则跳出循环,失败则进入下一轮for循环。 4.判断是否有其他线程在扩容table,有则帮忙扩容,扩容完成再添加元素。进入真正的put步骤 5.真正的put步骤。桶的位置不为空,遍历该桶的链表或者红黑树,若key已存在,则覆盖;不存在则将key插入到链表或红黑树的尾部。 并发问题:假如put操作时正好有别的线程正在对table数组(map)扩容怎么办? 答:暂停put操作

ConcurrentHashMap原理分析(1.7与1.8)-put和 get 需要执行两次Hash 多线程一起put的自旋锁问题还有 计算size 先不加锁计算3次,如果不对再给每个segme...

你。 提交于 2020-07-25 15:41:22
hashmap的扩容因子是0.75 原因 参考: HashMap默认加载因子为什么选择0.75?(阿里) ConcurrentHashMap 与HashMap和Hashtable 最大的不同在于:put和 get 两次Hash到达指定的HashEntry,第一次hash到达Segment,第二次到达Segment里面的Entry,然后在遍历entry链表 (1) 从1.7到1.8版本,由于HashEntry从链表 变成了红黑树所以 concurrentHashMap的时间复杂度从O(n)到O(log(n)) (2) HashEntry最小的容量为2 (3) concurrentHashMap 的1.7版本的 Segment ,它的初始化容量是16; (4)HashEntry在1.8中称为Node,链表转红黑树的值是8 ,当Node链表的节点数大于8时Node会自动转化为TreeNode,会转换成红黑树的结构( 阿里面试问的问题 ) 总结与思考 其实可以看出JDK1.8版本的ConcurrentHashMap的数据结构已经接近HashMap,相对而言,ConcurrentHashMap只是增加了同步的操作来控制并发,从JDK1.7版本的ReentrantLock+Segment+HashEntry,到JDK1.8版本中synchronized+CAS+HashEntry+红黑树

Java底层类和源码分析系列-ConcurrentHashMap源码分析

会有一股神秘感。 提交于 2020-04-17 17:52:34
要点 ConcurrentHashMap是HashMap的线程安全版本; 不允许[key,value]为null; 比Hashtable锁粒度更细; 采用CAS和synchronized来保证并发安全。数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树; 负载因子0.75; 默认初始化容量16; put时当前bucket为空时,使用CAS操作,将Node放入对应的bucket中; put时出现hash冲突,则采用synchronized; 查询操作不加锁,因此ConcurrentHashMap不是强一致性; ConcurrentHashMap内部采用的锁有synchronized、CAS、自旋锁、分段锁、volatile; 定义 public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>    implements ConcurrentMap<K,V>, Serializable 其中接口ConcurrentMap<K, V>来自Map<K, V>,添加了一些函数式接口方法,比如: default void forEach(BiConsumer<? super K, ? super V> action) default void replaceAll(BiFunction<? super K, ?