并发容器

JUC包下的14个并发容器,专门应付并发状态下线程安全的问题

介绍

  1. ConcurrentHashMap并发版的HashMap

  2. CopyOnWriteArrayList并发版的ArrayList

  3. CopyOnWriteArraySet并发版的Set

  4. ConcurrentLinkedQueue基于链表的并发队列(不阻塞)

  5. ConcurrentLinkedDeque基于双向列表的并发队列

  6. ConcurrentSkipListMap基于跳表的并发Map
    跳表:链表之上加了一层索引,就是一个新的链表,指向源数据的双数索引的位置。这一层的索引之上还可以增加索引,指向本层的双数位置。链表版的二分法。

  7. ConcurrentSkipListSet基于跳表的并发Set

  8. ArrayBlockingQueue阻塞队列基于数组

  9. LinkedBlockingQueue阻塞队列基于链表

  10. LinkedBlockingDeque阻塞队列基于双链表

  11. PriorityBlockingQueue线程安全的优先队列

  12. SynchronousQueue读写成对的队列

  13. LinkedTransferQueue基于链表的数据交换队列

  14. DelayQueue延时队列

一、ConcurrentHashMap

最常见的并发容器之一,常作用于并发场景下的缓存。底层还是哈希表,但是java8中有了优化。

  1. java7采用分段锁,即数据被分成16个部分。每个部分一把锁,各部分之间不冲突。
  2. java8放弃了分段锁,采用CAS乐观锁。
  3. java8中增加了同哈希值组成的链表长度超过8之后会转换成红黑树

二、CopyOnWriteArrayList

并发版的ArrayList, 底层结构还是数组。原理是增删改的操作会加锁,其中删改会创建新的数组并替换原来的。
适用于读多写少的情况,并且读没有加锁,所以可能读到脏数据。
读的效率高。

三、CopyOnWriteArraySet

并发版的Set, 内部使用CopyOnWriteArrayList实现的。每次add都会遍历内部数据,检查是否重复。不存在执行插入(加锁)
CopyOnWriteArrayList注意点类似,多了一条数据量不能太大,否则遍历成本过高。

四、ConcurrentLinkedQueue

基于链表实现的并发队列,不阻塞。使用乐观锁CAS保证现存的安全。内部是链表,理论上没有大小限制。

五、ConcurrentLinkedDeque

基于双向链表的并发队列,可以分别对于首尾进行操作。可以先进先出也可以先进后出。

六、ConcurrentSkipListMap

基于跳表SkipList的并发Map, 跳表是用空间换时间的数据结构。
每一层都是上一层的一半数据,类似于二分查找的实现方式来增加搜索效率。

七、ConcurrentSkipListSet

基于跳表的并发Set, 使用ConcurrentSkipListMap实现的

八、ArrayBlockingQueue

基于数组的阻塞队列,构造时需要指定大小。
添加元素时如果数组满了会阻塞,知道有位置可以放。(也可以设置返回或者超时等待)
通过锁ReentrantLock保证线程安全

九、LinkedBlockingQueue

基于链表的阻塞队列,相比不阻塞ConcurrentLinkedQueue多了容量的现在。不设置默认int的最大值

十、LinkedBlockingDeque

LinkedBlockingQueue类似,底层是双链表

十一、PriorityBlockingQueue

线程安全的优先队列,构造的时候需要传入一个比较器。内部会根据元素的优先级排序。读取的时候会根据优先级从高到低读取。
优先级低的可能会因为一直有更高级的元素而无法被读取。

十二、SynchronousQueue

数据同步交换队列,内部只能存一个元素。每次插入操作必须要取才能再次插入。
任何一个对SynchronousQueue写需要等到一个对SynchronousQueue的读操作,反之亦然

十三、LinkedTransferQueue

基于链表的交换队列,比SynchronousQueue更强大。
实现了TransferQueue接口,通过transfer方法放入元素时如果有线程在阻塞去元素,就会把元素直接给等待队列。如果没有人等待,则放到队列尾部,并阻塞直到有人读取。

十四、DelayQueue

可以使放入的元素在指定延时之后才被消费者取出,元素需要实现Delayed接口

你可能感兴趣的:(并发容器)