1. JDK1.7

⾸先将数据分为⼀段⼀段的存储,然后给每⼀段数据配⼀把锁,当⼀个线程占⽤锁访问其中⼀个段数据时,其他段的数据也能被其他线程访问。

ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。

Segment实现了ReentrantLock,所以Segment是⼀种可重⼊锁,扮演锁的⻆⾊。HashEntry⽤于存储键值对数据。

static class Segment<K,V> extends ReentrantLock implements Serializable {
}

⼀个ConcurrentHashMap⾥包含⼀个Segment数组。Segment的结构和HashMap类似,是⼀种数组和链表结构,⼀个Segment包含⼀个HashEntry数组,每个HashEntry是⼀个链表结构的元素,每个Segment守护着⼀个HashEntry数组⾥的元素,当对 HashEntry数组的数据进⾏修改时,必须⾸先获得对应的Segment的锁。

2. JDK1.8

ConcurrentHashMap取消了Segment分段锁,采⽤CASsynchronized来保证并发安全。数据结构跟HashMap1.8的结构类似,数组+链表/红⿊⼆叉树。Java 8 在链表⻓度超过⼀定阈值(8)时将链表(寻址时间复杂度为O(N))转换为红⿊树(寻址时间复杂度为O(log(N))

synchronized只锁定当前链表或红⿊⼆叉树的⾸节点,这样只要 hash 不冲突,就不会产⽣并发,效率⼜提升。

最后修改日期: 2021年12月15日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。