Java并发编程之ConcurrentHashMap详解

1.减小锁粒度

减小锁粒度是指缩小锁定对象的范围,从而减小锁冲突的可能性,从而提高系统的并发能力。减小锁粒度是一种削弱多线程锁竞争的有效手段,这种技术典型的应用是ConcurrentHashMap(高性能的HashMap)类的实现。对于HashMap而言,最重要的两个方法是get与set方法,如果我们对整个HashMap加锁,可以得到线程安全的对象,但是加锁粒度太大。Segment的大小也被称为ConcurrentHashMap的并发度。

2.ConcurrentHashMap实现

ConcurrentHashMap,它内部细分了若干个小的HashMap,称之为段(Segment)。默认情况下一个ConcurrentHashMap被进一步细分为16个段。

如果需要在ConcurrentHashMap中添加一个新的表项,并不是将整个HashMap加锁,而是首先根据hashcode得到该表项应该存放在哪个段中,然后对该段加锁,并完成put操作。在多线程环境中,如果多个线程同时进行put操作,只要被加入的表项不存放在同一个段中,则线程间可以做到真正的并行。

3.ConcurrentHashMap的size方法

ConcurrentHashMap的有效表项的数量为全部的有效表项之和。要获得这个信息需要取得所有字段的锁,然后再求和。但是ConcurrentHashMap的size方法并不总是这样执行,它会先使用无锁的方式求和,如果失败才会使用加锁的方法,这是同Hashtable相比的优势所在。

4.Hashtable的size方法

Hashtable的size方法只有一条语句,即return count,但是它做了同步,原因如下:

(1)同一时间只能有一条线程执行固定类的同步方法,但是对于类的非同步方法,可以多条线程同时访问。所以,这样就有问题了,可能线程A在执行Hashtable的put方法添加数据,线程B则可以正常调用size方法读取Hashtable中当前元素的个数,那读取到的值可能不是最新的,可能线程A添加了完了数据,但是没有对size++,线程B就已经读取size了,那么对于线程B来说读取到的size一定是不准确的。而给size方法加了同步之后,意味着线程B调用size方法只有在线程A调用put方法完毕之后才可以调用,这样就保证了线程安全性

(2)CPU执行代码,执行的不是Java代码,这点很关键,一定得记住。Java代码最终是被翻译成汇编代码执行的,汇编代码才是真正可以和硬件电路交互的代码。即使你看到Java代码只有一行,甚至你看到Java代码编译之后生成的字节码也只有一行,也不意味着对于底层来说这句语句的操作只有一个。一句"return count"假设被翻译成了三句汇编语句执行,完全可能执行完第一句,线程就切换了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值