Java并发学习之并发容器

上一篇博客主要学习了java中的同步容器,但在一些情况下,同步容器也会出现线程安全性的问题,如需要进行一些复合外部操作时,进行迭代时容易发生ConcurrentModificationException错误。

本篇博客主要学习一个相对于同步容器更好的容器集合:并发容器

一.并发容器

在Java 5.0后提供了多种并发容器类来改进同步容器的性能,它们所在的位置为:java.util.concurrent包中。

1.为何要引入并发容器?
我们知道,同步容器将所有对容器状态的访问都串行化来实现线程安全性,但这种方法会严重降低并发性能,当多个线程竞争容器的锁时,吞吐量将严重降低。
所以我们需要更加优秀的容器来解决这个问题,这时,并发容器就诞生了。

2.并发容器概述
并发容器中的类和同步容器的类基本对应,但并发容器中的类的并发性能更高,例如:
ConcurrentHashMap用来替代同步的类型的Map,例如HashTable
CopyOnWriteArrayList用来代替遍历操作为主情况下的同步的List。
而且并发容器接口中还添加了一些常见的复合操作,例如(若没有则添加,条件删除等)

通过并发容器来代替同步容器,可以极大的提高伸缩性并减低风险。

3.ConcurrentHashMap
1)ConcurrentHashMap是基于hashi的Map,它使用一种粒度更细的加锁机制来实现更大程度的共享,这种机制称之为分段锁(Lock Striping) 在这种机制中,任意数量的读取线程可以并发地访问Map,执行读取操作的线程和执行写入操作线程可以并发地访问Map,并且一定数量的写入线程可以并发地修改Map。

2)所以ConcurrentHashMap带来的结果是:在并发访问环境下将实现更高的吞吐量,在单线程环境中只损失非常小的性能。

3)ConcurrentHashMap以及其他的并发容器提供的迭代器不会抛出ConcurrentModificationException错误,因此不需要在迭代过程中对容器加锁。
原因是:
4)ConcurrentHashMap返回的迭代器具有弱一致性(Weakly Consistent) 。弱一致性的迭代器可以容忍并发的修改,当创建迭代器时会遍历已有的元素,并可以在迭代器被构造后将修改操作反映给容器。

5)由于上面的特性,所以对于一些需要在整个Map上进行计算的方法(如size和isEmpty),这些方法的语义被减弱以反映容器的并发特性,由于size返回的结果在计算时可能已经过期(略大或略小),所以它实际上是一个估计值。虽然这有点不好,但在并发环境下需要计算这两个属性的场景极少,因为并发环境下,size总是不断变化。

6)因此实际上我们用这些操作的准确性来换取其他重要操作的性能:get,put containsKey,remove等。

7)在ConcurrentHashMap中没有实现对Map加锁以提供独占访问,但与HashTable和synchronizedMap相比,它有着更多的优势,所以在大多数情况下,用ConcurrentHashMap来代替其他的同步Map能进一步提高代码的可伸缩性,除非应用程序需要加锁Map进行独占访问时,才考虑放弃它。

8)提供复合操作:
ConcurrentMap接口中的复合操作方法:
在这里插入图片描述

4.CopyOnWriteArrayList

1))CopyOnWirte容器的安全性在于:只要正确的发布一个事实不可变的对象,那么在访问该对象时就不再需要进一步的同步。在每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。

2)Copy On Write容器的迭代器保留一个指向底层基础数组的引用,这个数组当前位于迭代器的起始位置,由于它不会被修改,因此在对其进行同步时只需要确保数组内容的可见性,所以多个线程可以同时对这个容器进行迭代,而不会彼此干扰或者与修改容器的线程相互干扰。

3)Copy On Write容器返回的迭代器不会抛出ConcurrentModificationException,并且返回的元素与迭代器创建时的元素完全一致。

4)但是,这种方式每次修改容器时都会复制底层数组,这需要一定的开销,特别是当容器的规模较大时,所以,只有当迭代操作远远多于修改操作时才使用这个容器,这个建议很好。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值