您的位置:首页 > 编程语言 > Java开发

ConcurrentHashMap原理分析(JDK1.7)

2018-03-14 16:12 405 查看
声明:本文是根据JDK1.7版本进行分析
ConcurrentHashMap是一个线程安全的map集合,可以用来代理HashTable,使用锁分离技术来提高其效率。

首先,对比一下HashTable和ConcurrentHashMap:

相同点:都是线程安全的key-value存储集合;
不同点:1.HashTable是将所有涉及到多线程操作的方法都加上synchronized关键字,以至于锁住整个table,所有线程都胡金正这一把锁,在多线程环境下,是绝对安全的,但执行效率也是非常低下的;2.ConcurrentHashMap针对“锁住整个table”的操作进行优化,在多线程环境下,对不同数据集合操作时,其实没必要去竞争同一个锁,因为它们有不同的hash值,所以可以使用锁分离技术,将锁的粒度降低,利用多个锁来控制多个小的table。

ConcurrentHashMap分析

示意图

以下是ConcurrentHashMap的数据结构示意图,由一个Segment数组和多个HashEntry数组组成;Segment数组的意义就是将一个大的table分隔成多个小的table来进行加锁,每一个Segment元素存储的是HashEntry数组,HashEntry数组元素是链表,这个和HashMap的数据存储结构相同。


ConcurrentHashMap定义

concurrentHashMap继承自AbstractMap,实现了ConcurrentMap接口和Serializable接口,使它具有map属性和操作的同时,又具有多线程相关的属性,同时是可序列化的。

put操作

1.key和value都不能为null
2.求key的hash值,并计算出在segment数组中的索引位置
3.将元素放到Segment中,segment.put(key,hash,value,false)
4.每一个Segment进行put时,都会加锁
5.根据key的hash值,确定key在HashEntry数组的索引位置
6.获取要放入的HashEntry链的链头first,并遍历当前HashEntry链
7.如果first不为null
在该链中找到相同的key,用新的value值替换旧值,并退出循环,返回旧值
如果没有和key相同的,则插入到链头,返回null
8.最后释放锁

remove操作

1.求key的hash值
2.获取hash对应的Segment对象
3.在Segment内部进行删除,segment.remove(key,hash,null)
4.每一个Segment进行remove时,都会加锁
5.根据hash值,确定在HashEntry数组的索引位置
6.待删除节点的前一个节点指向待删除节点的后一个节点,相当于删除待删除节点
7.返回被删除的key对应的value值,最后释放锁
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: