最近学习java并发编程,少不了对java并发容器的学习,今天抽时间总结一下,有不正确之处还望互相学习:
一、ConcurrentHashMap
与hashMap和hashTable一样,ConcurrentHashMap提供了高并发的线程安全的Map实现,不但实现了的Map的功能,并且实现了接口ConcurrentMap所定义的原子操作。ConcurrentHashMap也是一个基于散列的Map,但它使用了一种完全不同的加锁策略来提高并发性和伸缩性。ConcurrentHashMap并不是将每个方法都在同一个锁上同步并使得每次只能有一个线程访问容器,而是采用一种粒度更细的加锁机制来实现更大程度的共享,这种机制叫做分段锁,默认是分成16段。在这种机制下,任意数量的读取线程可以并发的访问Map,执行读取操作的线程和执行写入操作的线程可以并发的访问map,并且一定数量的写入线程可以并发的修改Map,实现了在并发访问环境下将实现更高的吞吐量,而在单线程环境中只损失非常小的性能。
ConcurrentHashMap返回的迭代器具有弱一致性,而并非“及时失败”,弱一致性的迭代器可以容忍并发的修改,当创建迭代器时会遍历已有的元素,并可以(但是不保证)在迭代器被构造后将修改操作反映给容器。
二、ConcurrentLinkedQueue
ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。它采用了“wait-free”算法来实现,该算法是在Michael&Scott算法上进行了一些修改。
三、CopyOnWriteArrayList、CopyOnWriteArraySet
顾名思义,CopyOnWrite就是在write操作之前,对集合进行Copy,针对容器的任意改操作(add,set,remove之类),都是在容器的副本上进行的。并且在修改完之后,将原容器的引用指向修改后的副本。
CopyOnWriteArrayList用于替代同步的List,在某些情况下它提供了更好的并发性能,并且在迭代期间不需要对容器进行加锁或者复制(类似的,CopyOnWriteArraySet替代同步Set)。
“写入时复制(CopyOnWrite)”容器的安全性在于:只要正确的发布一个事实不可变的对象,那么在访问该对象时就不再需要进一步的同步,在每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。“写入时复制”容器的迭代器保留一个指向底层基础数组的引用,这个数组当前位于迭代器的起始位置,由于它不会被修改,因此在其对进行同步时只需确保数组内容的可见性。“写入时复制”容器返回的迭代器不会抛出COncurrentModificationException,并且返回的元素与迭代器创建时的元素完全一致,而不必考虑之后修改操作所带来的影响。
每当修改容器时都会复制底层数组,这需要一定的开销,特别是当容器的规模较大时,仅当迭代操作远远多于修改操作时,才应该使用“写入时复制”容器。这个准则很好的描述了许多事件通知系统:在分发通知时需要迭代已注册监听器链表,并调用每一个监听器,在大多数情况下,注册和注销事件监听器的操作远少于接收事件通知的操作。
四、BlockingQueue
阻塞队列(BlockingQueue) 是一个支持两个附加操作的队列。 这两个附加的操作支持阻塞的插入和移除方法。Queue是适合生产消费模式的数据结构。顾名思义,实现这个接口的都是阻塞队列。
其成员有:ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、LinkedTransferQueue、LinkedBlockingDeque、SynchronousQueue、PriorityBlockingQueue
以上就是对多线程并发容器的简单总结