5基础构建模块——并发容器
2017-04-15 12:54
453 查看
并发容器
通过并发容器来替代同步容器,提供性能,可以极大地提高伸缩性并降低风险。
java 5.0增加了两种新的容器类型:Queue和BlockingQueue。Queue的实现有:ConcurrentLinkedQueue,这是一个传统的先进先出的队列,PriorityQueue(非并发的)优先队列。Queue上的操作不会阻塞,如果队列为空,获取队列元素的操作将返回空值。
BlockingQueue扩展了Queue,增加了可阻塞的插入和获取操作。如果队列为空获取元素的操作,那么获取队列元素的操作将一直阻塞,直到队列出现一个可用的元素。如果队列已满(对于有界队列来说),那么插入元素的操作将一直阻塞,直到队列中出现可用的空间。
ConcurrentHashMap与HashMap一样也是基于散列的Map,但是它完全使用了不用的加锁策略来提供更高的并发性和可伸缩性。ConcurrentHashMap并不是在每个方法上都使用同一个锁来同步,而是使用了一种粒度更细的加锁机制来实现更大程度的共享,也就是分段锁。在这种机制中,任意数量的线程可以并发地访问Map,执行读取的线程和写入的线程可以并发的进行,并且一定数量的写入线程可以并发地修改Map。ConcurrentHashMap容器在迭代的时候不会抛出ConcurrentModificationException,因此不需要在迭代的过程加锁。ConcurrentHashMap返回的迭代器具有弱一致性(Weakly
Consistent),而并非“即使失败”。弱一致性的迭代器可以容忍并发的修改,当创建迭代器时会遍历所有的元素,并可以(但不保证)在迭代被构建后修改操作反应给容器。尽管这样,任然还是有权衡的因素。对于需要在对整个Map进行计算的方法,例如size和isEmpty,这些方法的语义被略微减弱了以反应容器的并发特性。size在计算结果时可能已经过期了,它实际上是一个估计值,因此size返回的是一个近似值不是精确值。
额外的原子操作
ConcurrentHashMap不能被加锁来进行独占的访问,因此我们无法使用客户端加锁来创建新的原子操作。这些复合操作都实现了原子操作,例如“若没有则添加”,“若相对则移除(Remove-If-Equal)”和“若相等则替换(Replace-If-Equal)”等。
CopyOnWriteArrayList
CopyOnWriteArrayList用于替换同步List,在某些情况下提供了更好的并发性能。并且迭代期间不需要对容器进行加锁或复制。“写入时复制(Copy-On-Write)”容器的线程安全在于,只要正确的发布一个事实的不可变对象,那么访问该对象就不需要加锁同步。每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。“写入时复制”容器迭代操作不会抛出ConcurrentModificationException,并且返回时的元素与迭代器创建时的元素完全一致,而不必考虑之后修改操作带来的影响。“写入时复制”容器修改操作需要一定的开销,所以仅当迭代操作远远多于修改操作的时候,才应该使用它。
通过并发容器来替代同步容器,提供性能,可以极大地提高伸缩性并降低风险。
java 5.0增加了两种新的容器类型:Queue和BlockingQueue。Queue的实现有:ConcurrentLinkedQueue,这是一个传统的先进先出的队列,PriorityQueue(非并发的)优先队列。Queue上的操作不会阻塞,如果队列为空,获取队列元素的操作将返回空值。
BlockingQueue扩展了Queue,增加了可阻塞的插入和获取操作。如果队列为空获取元素的操作,那么获取队列元素的操作将一直阻塞,直到队列出现一个可用的元素。如果队列已满(对于有界队列来说),那么插入元素的操作将一直阻塞,直到队列中出现可用的空间。
ConcurrentHashMap与HashMap一样也是基于散列的Map,但是它完全使用了不用的加锁策略来提供更高的并发性和可伸缩性。ConcurrentHashMap并不是在每个方法上都使用同一个锁来同步,而是使用了一种粒度更细的加锁机制来实现更大程度的共享,也就是分段锁。在这种机制中,任意数量的线程可以并发地访问Map,执行读取的线程和写入的线程可以并发的进行,并且一定数量的写入线程可以并发地修改Map。ConcurrentHashMap容器在迭代的时候不会抛出ConcurrentModificationException,因此不需要在迭代的过程加锁。ConcurrentHashMap返回的迭代器具有弱一致性(Weakly
Consistent),而并非“即使失败”。弱一致性的迭代器可以容忍并发的修改,当创建迭代器时会遍历所有的元素,并可以(但不保证)在迭代被构建后修改操作反应给容器。尽管这样,任然还是有权衡的因素。对于需要在对整个Map进行计算的方法,例如size和isEmpty,这些方法的语义被略微减弱了以反应容器的并发特性。size在计算结果时可能已经过期了,它实际上是一个估计值,因此size返回的是一个近似值不是精确值。
额外的原子操作
ConcurrentHashMap不能被加锁来进行独占的访问,因此我们无法使用客户端加锁来创建新的原子操作。这些复合操作都实现了原子操作,例如“若没有则添加”,“若相对则移除(Remove-If-Equal)”和“若相等则替换(Replace-If-Equal)”等。
CopyOnWriteArrayList
CopyOnWriteArrayList用于替换同步List,在某些情况下提供了更好的并发性能。并且迭代期间不需要对容器进行加锁或复制。“写入时复制(Copy-On-Write)”容器的线程安全在于,只要正确的发布一个事实的不可变对象,那么访问该对象就不需要加锁同步。每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。“写入时复制”容器迭代操作不会抛出ConcurrentModificationException,并且返回时的元素与迭代器创建时的元素完全一致,而不必考虑之后修改操作带来的影响。“写入时复制”容器修改操作需要一定的开销,所以仅当迭代操作远远多于修改操作的时候,才应该使用它。
相关文章推荐
- Java 集合7:丰富的并发基础构建模块1 - 容器部分
- Java并发编程基础构建模块(02)——并发容器
- Java并发编程基础构建模块(02)——并发容器
- Java并发编程学习——基础构建模块
- [Java 并发] Java并发编程实践 思维导图 - 第五章 基础构建模块
- JAVA并发编程学习笔记------基础构建模块
- Java 并发编程之基础构建模块 (二)
- Java并发编程基础构建模块(01)——同步容器类
- 并发编程实战学习笔记(三)——基础构建模块
- Java并发基础构建模块简介
- java并发编程实战学习(3)--基础构建模块
- Java 并发编程实战之 基础构建模块
- Java并发基础构建模块简介
- Java 并发编程之基础构建模块
- 【Java并发.5】基础构建模块
- Java并发读书学习笔记(四)——基础构建模块
- Java并发编程实战:并发基础构建模块
- Java并发基础构建模块简介
- Java并发编程基础构建模块(06)——高效缓存总结示例
- 《java并发编程实战》基础构建模块(六)