ConcurrentHashMap

ConcurrentHashMap中引入了分段锁的概念,可以理解为将一个大的Map拆分成N个小的Hashtable(通过synchronized保证线程安全),被称为segments,根据key.hashCode来决定把key放到哪个Hashtable中。

对于操作同一segment的两个线程,后一个将被阻塞;对于操作不同segment的两个线程,互不影响--以此相对于Hashtable提高效率。ConcurrentHashMap缺省情况下生成16个segments,也就是允许16个线程并发更新而尽量没有阻塞、锁的争用。

HashMap或者ArrayList边遍历边删除会抛异常,因此需要使用Iterator删除元素;ConcurrentHashMap边遍历边删除或增加操作不会产生影响,即使多个线程一起删除、添加元素也没问题。

一个线程对ConcurrentHashMap增加数据,另外一个线程在遍历时就能获得。

get方法不涉及到锁,即获得对象时没有使用锁;

ConcurrentHashMap允许边遍历边更新,即在使用Iterator进行的遍历的时候,可以使用put、remove方法对Map进行更新,若想获得当前的全部数据,可以使用synchronized将ConcurrentHashMap对象包装,在{}进行Iterator操作;

HashMap或ArrayList在边遍历边删除时会报java.util.ConcurrentModificationException异常,不过可以用迭代器解决;

对ConcurrentHashMap边遍历边删除或者增加操作不会产生异常,遍历的时候都能获得最新值,即使多个线程一起删除、添加也没有问题。

但是,ConcurrentHashMap只保证了原子操作的线程安全:
map.put(key, map.get(key) + 1);
以上操作并非原子操作,包含了三个步骤:
1.map.get
2.+1
3.map.put

其中第1步和第3步,单独来说是线程安全的,可以由ConcurrentHashMap保证;如果map是一个共享对象,线程A执行map.get时,线程B可能在执行map.put,则当线程A执行到map.put时,线程A中的数据已经是脏数据,导致线程不安全;

为了保证线程安全,需要使用同步代码块synchronized(共享变量),之后可以将ConcurrentHashMap换成HashMap,检验ConcurrentHashMap是否还有必要。

转载于:https://www.cnblogs.com/yuanfei1110111/p/10134350.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值