ConcurrentHashMap类的理解

ConcurrentHashMap类的理解

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

 

锁分离

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

HashmapConcurrentHashMap的结构比较

 

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

 ConcurrentHashMap的详细结构

 


 

hashEntry在源码中的表示如下,其keyhashnext均为final,为不可变,valuevolatile

意味着:

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

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

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

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

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

 

Segment中的数据结构,

278行出,就是segment对应的hashTable

 

Put 方法

 



 

 

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

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

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

4.在segmentput方法中

 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行,执行lock519行获取链头first。使e指向first。通过512while循环找到需要删除的HashEntry位置。

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

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

 

 

Get

 

 


 

 

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

这是hashMap下的get方法

 

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


Size()


在调用size时,会设计到跨段操作。在742~747进行统计的时候,需要分别对每段进行lock。然后获取数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值