ConcurrentHashMap原理分析和总结(JDK1.8)
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操作