ConcurrentHashMap源码,看我这篇就够了

打印 上一主题 下一主题

主题 882|帖子 882|积分 2646

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
思考:HashTable是线程安全的,为什么不推荐使用?
HashTable是一个线程安全的类,它使用synchronized来锁住整张Hash表来实现线程安全,即每次锁住整张表让线程独占,相当于所有线程进行读写时都去竞争一把锁,导致效率非常低下。
1 ConcurrentHashMap 1.7

在JDK1.7中ConcurrentHashMap采用了数组+分段锁的方式实现
Segment(分段锁)-减少锁的粒度
ConcurrentHashMap中的分段锁称为Segment,它即类似于HashMap的结构,即内部拥有一个Entry数组,数组中的每个元素又是一个链表,同时又是一个ReentrantLock(Segment继承了ReentrantLock)。
1.存储结构

Java 7 版本 ConcurrentHashMap 的存储结构如图:


ConcurrnetHashMap 由很多个 Segment 组合,而每一个 Segment 是一个类似于 HashMap 的结构,所以每一个 HashMap 的内部可以进行扩容。但是 Segment 的个数一旦初始化就不能改变,默认 Segment 的个数是 16 个,所以可以认为 ConcurrentHashMap 默认支持最多 16 个线程并发。
2. 初始化

通过 ConcurrentHashMap 的无参构造探寻 ConcurrentHashMap 的初始化流程。
  1.     /**
  2.      * Creates a new, empty map with a default initial capacity (16),
  3.      * load factor (0.75) and concurrencyLevel (16).
  4.      */
  5.     public ConcurrentHashMap() {
  6.         this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
  7.     }
复制代码
无参构造中调用了有参构造,传入了三个参数的默认值,他们的值是。
  1.     /**
  2.      * 默认初始化容量,这个容量指的是Segment 的大小
  3.      */
  4.     static final int DEFAULT_INITIAL_CAPACITY = 16;
  5.     /**
  6.      * 默认负载因子
  7.      */
  8.     static final float DEFAULT_LOAD_FACTOR = 0.75f;
  9.     /**
  10.      * 默认并发级别,并发级别指的是Segment桶的个数,默认是16个并发大小
  11.      */
  12.     static final int DEFAULT_CONCURRENCY_LEVEL = 16;
  13. Segment下面entryset数组的大小是用DEFAULT_INITIAL_CAPACITY/DEFAULT_CONCURRENCY_LEVEL求出来的。
复制代码
接着看下这个有参构造函数的内部实现逻辑。
[code]@SuppressWarnings("unchecked")public ConcurrentHashMap(int initialCapacity,float loadFactor, int concurrencyLevel) {    // 参数校验    if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel > segmentShift) & segmentMask)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

玛卡巴卡的卡巴卡玛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表