美文网首页
ConcurrentHashMap 1.8

ConcurrentHashMap 1.8

作者: 晨曦_lcq | 来源:发表于2020-08-23 22:09 被阅读0次

描述

Map线程安全的实现,通过数组+链表实现。关键属性:sizeCtl。

实现流程

  • 构造器:调用构造器并不会初始化数组

    • 无参构造器:里面啥都没有,空的方法
    • 带初始容量构造器:实际初始容量不是是参数值,而是参数值的2倍。通过tableSizeFor得到大于或等于参数值2次幂的值
      public LcqConcurrentHashMap(int initCap) {
        if (initCap < 0) {
            throw new IllegalArgumentException();
        }
        // 得到的容量大小肯定是传值的2次幂
        int cap = initCap >= MAXIMUM_CAPACITY>>>1 ? MAXIMUM_CAPACITY : tableSizeFor(initCap + initCap >> 1 + 1);
        // sizeCtl为正数,如果没有初始化表示容量,如果已经初始化表示扩容阀值。这里表示容量
        this.sizeCtl = cap;
      }
      
      private static final int tableSizeFor(int c) {
        // 防止整型越界
        int n = c - 1;
        // 保证得到2次幂的值
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
      }
      
      
  • put新增元素,循环迭代table(存放节点的数组),直到table不为空或者table长度不为0

    • 如果table为空或者table.length为0,则初始化数组。
      • while循环判断table是否为空,如果为空并且sizeCtl为-1,表示有其他线程正在初始化,Thread.yield()让出资源让其他线程执行完;
      • 如果sizeCtl大于等于0,cas将sc设置为-1(表示正在初始化),初始化节点数组并赋值给table,同事将sizeCtl设置为扩容的阀值,sizeCtl=table.length - table.length >>>2;
    • 如果

相关文章

网友评论

      本文标题:ConcurrentHashMap 1.8

      本文链接:https://www.haomeiwen.com/subject/mcwwjktx.html