ConcurrentHashMap源码分析--Java8

本文详细分析了Java8 ConcurrentHashMap的实现原理,包括其使用CAS算法、无锁及同步策略。文章指出,尽管使用了CAS,但在特定情况下依然会使用锁。还介绍了其内部结构、容量限制、扩容机制、TreeBin及其转换条件,以及put和isEmpty等关键操作的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        本文首写于有道云笔记,并在小组分享会分享,先整理发布,希望和大家交流探讨。云笔记地址

概述:
1、设计首要目的:维护并发可读性(get、迭代相关);次要目的:使空间消耗比HashMap相同或更好,且支持多线程高效率的初始插入(empty table)。
2、HashTable 线程安全,但采用synchronized,多线程下效率低下。线程1put时,线程2无法put或get。

实现原理:
锁分离:
        在HashMap的基础上,将数据分段存储, ConcurrentHashMap由多个Segment组成,每个Segment都有把锁。Segment下包含很多Node,也就是我们的键值对了。

如果还停留在锁分离、Segment,那已经out了。
Segment虽保留,但已经简化属性,仅仅是为了兼容旧版本。

  • CAS算法unsafe.compareAndSwapInt(this, valueOffset, expect, update);  CAS(Compare And Swap),意思是如果valueOffset位置包含的值与expect值相同,则更新valueOffset位置的值为update,并返回true,否则不更新,返回false。
  • 与Java8的HashMap有相通之处,底层依然由“数组”+链表+红黑树
  • 底层结构存放的是TreeBin对象,而不是TreeNode对象;
  • CAS作为知名无锁算法,那ConcurrentHashMap就没用锁了么?当然不是,hash值相同的链表的头结点还是会synchronized上锁。 

private static final int MAXIMUM_CAPACITY = 1 << 30; // 2的30次方=1073741824

private static final intDEFAULT_CAPACITY = 16;

static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // MAX_VALUE=2^31-1=2147483647

private static finalint DEFAULT_CONCURRENCY_LEVEL = 16;

private static final float LOAD_FACTOR = 0.75f;

static final int TREEIFY_THRESHOLD = 8; // 链表转树阀值,大于8时

static final int UNTREEIFY_THRESHOLD = 6; //树转链表阀值,小于等于6(tranfer时,lc、hc=0两个计数器分别++记录原bin、新binTreeNode数量,<=UNTREEIFY_THRESHOLD 则untreeify(lo))。【仅在扩容tranfer时才可能树转链表】

static final int MIN_TREEIFY_CAPACITY = 64;

private static final int MIN_TRANSFER_STRIDE = 16;

private static int RESIZE_STAMP_BITS = 16;

private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1; // 2^15-1,help resize的最大线程数

private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS// 32-16=16,sizeCtl中记录size大小的偏移量

static final int MOVED     = -1; // hash for forwarding nodes(forwarding nodes的hash值)、标示位

static final int TREEBIN   = -2; // hash for roots of trees(树根节点的hash值)

static final int RESERVED  = -3; // hash for transient reservations(ReservationNode的hash值)

static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash

static final int NCPU = Runtime.getRuntime().availableProcessors(); // 可用处理器数量

 /**

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值