ConcurrentHashMap使用示例以及原理

本文详细介绍了Java中的ConcurrentHashMap,它不仅提供了线程安全的特性,还能有效避免并发操作时的数据不一致问题。通过示例展示了如何使用ConcurrentHashMap以及其接口方法,如putIfAbsent,以确保并发统计单词次数等业务的正确性。此外,文章还探讨了使用AtomicLong优化性能以及在特定场景下避免对象重复创建的策略,最后推荐了Guava的AtomicLongMap和MapMaker作为更优选择。
摘要由CSDN通过智能技术生成

 

ConcurrentHashMap通常只被看做并发效率更高的Map,用来替换其他线程安全的Map容器,比如Hashtable和Collections.synchronizedMap。实际上,线程安全的容器,特别是Map,应用场景没有想象中的多,很多情况下一个业务会涉及容器的多个操作,即复合操作,并发执行时,线程安全的容器只能保证自身的数据不被破坏,但无法保证业务的行为是否正确。

举个例子:统计文本中单词出现的次数,把单词出现的次数记录到一个Map中,代码如下:

 

?

1

2

3

4

5

6

7

8

privatefinal Map<String, Long> wordCounts = newConcurrentHashMap<>();

 

publiclong increase(String word) {

    Long oldValue = wordCounts.get(word);//两个线程同时查询word,都为空,下面都会put

    Long newValue = (oldValue == null) ? 1L : oldValue + 1;

    wordCounts.put(word, newValue);     

    returnnewValue;

}

如果多个线程并发调用这个increase()方法,increase()的实现就是错误的,因为多个线程用相同的word调用时,很可能会覆盖相互的结果,造成记录的次数比实际出现的次数少。

 

除了用锁解决这个问题,另外一个选择是使用ConcurrentMap接口定义的方法:

 

?

1

2

3

4

5

6

publicinterface ConcurrentMap<K, V> extendsMap<K, V> {

    V putIfAbsent(K key, V value);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值