zoukankan      html  css  js  c++  java
  • concurrenthashmap jdk1.8

    参考:https://www.jianshu.com/p/c0642afe03e0

    CAS的思想很简单:三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做,并返回false。

    细节参考:https://www.jianshu.com/p/fb6e91b013cc

    参考:http://blog.csdn.net/u010412719/article/details/52145145

       https://www.jianshu.com/p/c0642afe03e0

    总结:CAS操作就是将内存中的值和预期中的值比较,相等则修改,并返回true,不相等返回false
    casTabAt(Node<K,V>[] tab, int i, Node<K,V> c, Node<K,V> v) (将c与tab[i]比较)设置节点上的值
    相对于synchronized操作要更快。

    concurrenthashmap在jdk中1.8中利用CAS+Synchronized来保证并发更新的安全,没有利用segment分段锁的机制。
    concurrentHashMap扩容
    1、put新增一个节点,计算hash值。
    检验entry数据是否初始化?没有,那么初始化initTable
    检验table[i]是否为null?为null,利用cas添加节点
    不为null,判断是否在扩容?在扩容帮助扩容,没有则helpTransfer帮助扩容
    以上情况均不符合,synchronized锁定头节点,判断为链表节点,则插入链表的尾部
    判断为树节点,则按照树添加节点
    如果元素>=8?转化为树{
    如果数组<64,扩容,只有当sizeCtl>0,才能扩容trasfer方法
    如果数组>64,转化为树
    }


    2、扩容

    情况1:当元素新增字节后,链表个数到达8,就会调用treeifBin把链表转化为
    红黑树。在转化之前,如果数组长度小于阈值MIN_TREEIFY_CAPACITY,默认是64,
    就会调用treePresize方法将数组扩大到原来的两倍。触发transfer方法,调整节点
    的位置。
    情况2:新增节点后,调用addCount方法记录元素个数,当达到阈值时就会调用transfer扩容

    如果槽点为链表,由于是扩大到原来的两倍,transfer中就会利用fn&n快速将链表中的元素分为两类,分别生成一个和最后一节点fn&n相同的顺序列表,一个和最后一节点fn&n不同的反序列表,通过CAS把两者存储在新的数组中。

    如果槽位为红黑树,则构造两个树节点,遍历红黑树,同样根据hash&n把节点分为两类,插入两个树节点的链表中。如果链表小于等于UNTREEIFY_THRESHOLD(6),则转化为普通列表。如果另一个节点的长度为0,那么将原始红黑树取过来。不然就根据链表重新创建树。最后通过CAS存储到新的数组中。

    3、get
    1、判断table是否为空,为空直接返回null
    2、计算keyhash值,通过tabAt获得制定点的node,然后遍历链表或者树结构找到对应的点返回value

    4、size
    通过mappingCount获取size,主要时利用long替代int
    但是两者计算出来都是一个估值,并没有像jdk1.7那样不断循环计算准确值

    setTabAt(Node<K,V>[] tab, int i, Node<K,V> v){
    //设置obj对象中offset偏移地址对应的object型field的值为指定值
    U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
    }上锁时,设置节点上的值


    tabAt(Node<K,V>[] tab, int i) 获取索引处node,保证读到最新对象

  • 相关阅读:
    Django模板语言进阶
    ORM基础之ORM介绍和基础操作
    ORM关于表那些事
    ORM之基础操作进阶
    ORM基础之字段及其参数介绍
    AJAX初识(原生JS版AJAX和Jquery版AJAX)
    AJAX异步、sweetalert、Cookie和Session初识
    在一个千万级的数据库查寻中,如何提高查询效率?
    A fatal error has been detected by the Java Runtime Environment(jdk 1.6的一个BUG)
    外网映射工具地址
  • 原文地址:https://www.cnblogs.com/L-a-u-r-a/p/8557401.html
Copyright © 2011-2022 走看看