ConcurrentHashMap 1.8

描述

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;
    • 如果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。