多线程系列提高(5)--几种重要的并发容器类

一、ConcurrentHashMap

与hashMap一样,ConcurrentHashMap也是一个基于散列的Map,但它使用了一种完全不同的加锁策略来提高并发性和伸缩性。ConcurrentHashMap并不是将每个方法都在同一个锁上同步并使得每次只能有一个线程访问容器,而是采用一种粒度更细的加锁机制来实现更大程度的共享,这种机制叫做分段锁,默认是分成16段。在这种机制下,任意数量的读取线程可以并发的访问Map,执行读取操作的线程和执行写入操作的线程可以并发的访问map,并且一定数量的写入线程可以并发的修改Map,实现了在并发访问环境下将实现更高的吞吐量,而在单线程环境中只损失非常小的性能。
ConcurrentHashMap返回的迭代器具有弱一致性,而并非“及时失败”,弱一致性的迭代器可以容忍并发的修改,当创建迭代器时会遍历已有的元素,并可以(但是不保证)在迭代器被构造后将修改操作反映给容器。

二、CopyOnWriteArrayList

CopyOnWriteArrayList用于替代同步的List,在某些情况下它提供了更好的并发性能,并且在迭代期间不需要对容器进行加锁或者复制(类似的,CopyOnWriteArraySet替代同步Set)。
“写入时复制(CopyOnWrite)”容器的安全性在于:只要正确的发布一个事实不可变的对象,那么在访问该对象时就不再需要进一步的同步,在每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。“写入时复制”容器的迭代器保留一个指向底层基础数组的引用,这个数组当前位于迭代器的起始位置,由于它不会被修改,因此在其对进行同步时只需确保数组内容的可见性。“写入时复制”容器返回的迭代器不会抛出COncurrentModificationException,并且返回的元素与迭代器创建时的元素完全一致,而不必考虑之后修改操作所带来的影响。
每当修改容器时都会复制底层数组,这需要一定的开销,特别是当容器的规模较大时,仅当迭代操作远远多于修改操作时,才应该使用“写入时复制”容器。这个准则很好的描述了许多事件通知系统:在分发通知时需要迭代已注册监听器链表,并调用每一个监听器,在大多数情况下,注册和注销事件监听器的操作远少于接收事件通知的操作。

发布了104 篇原创文章 · 获赞 56 · 访问量 9万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章