ConcurrentHashMap的优点以及实现…

相信每个JAVA程序员都了解HashMap,最大的问题是线程不安全,因为方法中不涉及到同步,也正因为如此,HashMap的效率非常高,在不涉及线程安全的程序中广泛被应用。然而当涉及到多线程作业时,就会出现一些问题。为了解决这些问题JAVA提供了Hashtable,这是一种整体加锁的数据结构,然而效率不敢恭维。这时候就有了ConcurrentHashMap。

一个例子说明三者关系:
前提:某个卫生间共有16个隔间。

HashMap:每个隔间都没锁门,有人想上厕所,管理员指给他一个隔间,里面没人的话正常用,里面有人的话把这个人赶出来然后用。
优点,每个人进来不耽误都能用;缺点,每一个上厕所的人都有被中途赶出来的危险。

Hashtable:在卫生间外面安装一个大门,有人想上厕所,问管理员要一个钥匙进门,把门反锁用,用完后出来,把钥匙交换给管理员。在这个人上厕所期间,其他所有人都必须在外面排号。
优点,每个人都能安心上完厕所;缺点,卫生间外面可能已经出了人命。 =_=

ConcurrentHashMap:在卫生间每个隔间安装门锁,有人想上厕所,管理员指给他一个隔间,进来后这个隔间如果没人在用则直接用,如果有人正在用,则排号。在这期间其他人会按规则分到不同的隔间,重复上述行为。
优点:每个人都能安心上厕所,外面排队的也被均匀分摊。缺点:。。。

ConcurrentHashMap实现的原理
ConcurrentHashMap把Map分成了N个Segment(默认16),其中 Segment是线程同步的, 相当于分成了N个Hashtable。当实现Put方法时,在key值经过正常的hash后,还要再经过一次segmentForHash算法,用来分配具体防盗哪个Segment 后来的线程如果经过计算也是放在这个 Segment下,则需要先获取锁,如果计算得出应该放在其他的Segment,则正常执行,不会影响效率,以此实现线程安全。 ConcurrentHashMap 使用锁分离技术,只要多个修改操作不发生在同一个 Segment上,它们就可以并发进行。
有些方法需要跨段,比如size()和containsValue(),需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。这里“按顺序”是很重要的,否则极有可能出现死锁,在ConcurrentHashMap内部,段数组是final的,并且其成员变量实际上也是final的,但是,仅仅是将数组声明为final的并不保证数组成员也是final的,这需要实现上的保证。这可以确保不会出现死锁,因为获得锁的顺序是固定的。

附一些源码:
ConcurrentHashMap的优点以及实现原理

ConcurrentHashMap的优点以及实现原理

ConcurrentHashMap的优点以及实现原理





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值