您的位置:首页 > 移动开发 > Android开发

ConcurrentHashMap类的理解

2015-07-02 15:56 1341 查看
ConcurrentHashMap类的理解
ConcurrentHashMap是java 中支持高并发,高吞吐量的hashMap实现。ConcurrnetHashMap是基于线程安全的一个类。曾看到某个帖子http://blog.sina.com.cn/s/blog_605f5b4f0100qsio.html,在针对于Collections.synchronizedMap、ConcurrentHashMap、Hashtable,进行性能测试。模拟1000个并发,每个测试1000次操作,循环测试100轮,最后读写对应的时间分别为:(6544ms,707ms),(5960ms,650ms),(6719ms,713ms)(此数据依据当前运行条件,有浮动,但是得出的结论是,ConcurrentHashMap比其余两个在读和取上都会快一些)。

 

锁分离

通过HashMap分析知道,Synchronized是针对整张hash表的,即每次锁住整张表,而ConcurrentHashMap允许多个修改操作并发进行。其关键是采用了锁分离技术。ConCurrentHashMap内部使用段(segment)来表示这些不同的部分,每个段就是一个小的hashtable。但是size()和containsValue(),则可能需要锁住整个表。

Hashmap与ConcurrentHashMap的结构比较

 


每一个segment管理着一个小的hashtable,所以在多线程下访问ConcurrentHashMap,只需对对应segment进行加锁即可。

 ConcurrentHashMap的详细结构

 




 

hashEntry在源码中的表示如下,其key,hash,next均为final,为不可变,value为volatile。

意味着:

1.我们的key尽量使用int或者string类型做为key。

2.next为final,不能从hash的中间或者尾部添加或者删除节点,因为这样做需要修改next的引用值。

  2.1 对于put操作,新加入的元素,都是放在hash链的链头,

  2.2 对于remove操作,是将要删除的前面的所有节点复制一遍,然后,复制后的最后一个节点,指向要删除节点的下一个节点。

3.对于value为volatile类型,每次访问value时,都是去内存中取最新的值。

 


Segment中的数据结构,

278行出,就是segment对应的hashTable

 

Put 方法

 






 

 

1.先根据传递过来的key获取其hashcode,然后再hash一次得到segment的hash值。

2.通过segmentFor,寻找到key值对应的segment段。

3.调用segment中的put方法,将对应的值put进入对应的segment的hashtable中。

4.在segment的put方法中

 4.1 416行,通过lock给此段加锁

 4.2 在423行获取到链头,通过425行的while循环,找到对应的hashentry。

 4.3 在437行,如果没有找到,即网链表中新增加一个hashEntery。

 


4.4 437行的hashEntry的构造函数如上图代码。将新添加的next指向first,然后tab[index]=新添加的HashEntry。就这样将新添加的元素添加到了链表头

 

Remove

 




 

1.Segment寻找方式与put一样

2.真正执行remove的是segment类中的remove方法

3.在514行,执行lock,519行获取链头first。使e指向first。通过512的while循环找到需要删除的HashEntry位置。

4.真正重要在534~536行,此处通过for循环,将要删除的节点前面所有的节点重新复制一遍,在重新设置起next。

 例如原来的链表 为1->2->3->4->5 ,如果需删除的节点为4,通过for循环后,链表将变成3->2->1->5.节点前的链表顺序将会倒叙

 

 

Get

 

 




 

 

其寻找方式与put差不多,这里就不再重复。只是这里将锁加载读取value处。。。。。。

这是hashMap下的get方法

 


在conCureentHashmap中,get,put方法是没有对key进行空判断的。所以在conCureentHashmap是不允许使用null做为key

Size()



在调用size时,会设计到跨段操作。在742~747进行统计的时候,需要分别对每段进行lock。然后获取数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息