ConcurrentHashMap源码解析(一)之------基础属性

HashMap在单线程中非常好用,也不会出现什么问题。但是在多线程中,HashTable的效率太低。后面提供了ConcurrentHashMap解决多线程的问题,后续都以1.8的为对象进行研究。
在1.8中,ConcurrentHashMap的设计与HashMap保持一致,使用了链表和红黑树的组合,当一个链表上的节点数超过8,且总个数超过64,就会触发转为红黑树。

一:开始先了解ConcurrentHashMap中的基础属性

1.最大值:

  private static final int MAXIMUM_CAPACITY = 1 << 30;

2.默认值:

    private static final int DEFAULT_CAPACITY = 16;

3.负载因子

  private static final float LOAD_FACTOR = 0.75f;

4.树化阈值

    static final int TREEIFY_THRESHOLD = 8;

5.联合 TREEIFY_THRESHOLD控制桶位是否树化,只有当table数组长度达到64.且某个桶位的链表长度达到8,才会真正的树化

static final int MIN_TREEIFY_CAPACITY = 64;

6.扩容相关,计算扩容时生成一个 表示戳

    private static int RESIZE_STAMP_BITS = 16;
  1. 65535 表示 并发扩容最多线程数
   private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1;

8.扩容相关

private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS;

9.当node节点的hash值 为-1时,表示当前节点为FWD节点

static final int MOVED     = -1;

10.当node节点的hash值 为-2时, 表示当前节点已经树化,且当前节点为TreeBin对象,TreeBin对象代理操作红黑树

static final int TREEBIN   = -2; 

11.可以将一个负数通过位与运算后得到正数,但是不是取绝对值

  static final int HASH_BITS = 0x7fffffff; 

12.系统CPU的数量

 static final int NCPU = Runtime.getRuntime().availableProcessors();

13.散列表,长度一定是2次方数

 transient volatile Node<K,V>[] table;

14.扩容过程中,会将扩容中的新table 赋值给nextTable 保持引用,扩容结束之后,这里会被设置为null

private transient volatile Node<K,V>[] nextTable;

15.未发生竞争时,或者当前LongAdder 处于加锁状态时,增量累加到baseCount

  private transient volatile long baseCount;

/**
* sizeCtl < 0
* 1. -1 表示当前table正在初始化(有线程在创建table数组),当前线程需要自旋等待
* 2.表达当前map正在进行扩容 高16位表示:扩容的标识戳 低16位: 表示 1+N Thread 当前参与并发扩容的线程数量
*
* sizeCtl = 0;
* 表示创建map时,使用DEFALUT_CAPACITY 为大小
*
* sizeCtl > 0;
* 1.如果table未初始化,表示初始化大小;
* 2.如果table已经初始化了,表示下次扩容时触发条件(阈值)
*
*/

private transient volatile int sizeCtl;

17.扩容过程中,记录当前进度。所有线程都需要从transferIndex中分配区间任务,去执行自己的任务

private transient volatile int transferIndex;

18.LongAdder中的 cellsBuzy 0表示当前LongAdder对象无锁状态,1表示当前LongAdder对象加锁状态

    private transient volatile int cellsBusy;

19.LongAdder 中的cells数组,当baseCount发生竞争后,会创建cells数组.线程会通过计算hash值 取到 自己的cell,将增量累加到指定cell中

 private transient volatile CounterCell[] counterCells;

20.表示sizeCtl属性在concurrentHashMap中内存便宜地址

  private static final long SIZECTL;

21.表示transferIndex属性在concurrentHashMap中内存便宜地址

 private static final long TRANSFERINDEX;

22.表示baseCount属性在concurrentHashMap中内存便宜地址

private static final long BASECOUNT;

23.表示cellsBusy属性在concurrentHashMap中内存便宜地址

    private static final long CELLSBUSY;

24.表示cellValue属性在concurrentHashMap中内存便宜地址

 private static final long CELLVALUE;

25.表示数组的第一个元素的偏移地址

    private static final long ABASE;

26.spread()方法
该方法是进行与位运算

static final int spread(int h) {
        //h为key值得hash值,将高16位也参与运算,然后与int最大值进行&运算(效果为将值变为正数,其他位置不变)
        //HASH_BITS为int最大值,最高位为0
        //HashMap中没有处理为正数的步骤,这里负数有其它含义,查看节点类型
        return (h ^ (h >>> 16)) & HASH_BITS;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

virtuousOne

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值