【Java多线程】并发容器Collections

本文介绍了Java并发容器,强调了在迭代时修改容器会导致`ConcurrentModificationException`,并提出了并发容器的特性和分类。重点讲解了并发容器如CopyOnWriteArrayList、ConcurrentHashMap及其锁分段机制,并介绍了不同类型的阻塞队列,如ArrayBlockingQueue、PriorityBlockingQueue等,以及它们的实现原理和应用场景。
摘要由CSDN通过智能技术生成

1.迭代器与ConcurrentModificationException

使用Iterator迭代容器或使用使用for-each遍历容器,在迭代过程中修改容器会抛出ConcurrentModificationException异常。想要避免出现ConcurrentModificationException,就必须在迭代过程持有容器的锁。但是若容器较大,则迭代的时间也会较长。那么需要访问该容器的其他线程将会长时间等待。从而会极大降低性能。

若不希望在迭代期间对容器加锁,可以使用”克隆”容器的方式。使用线程封闭,由于其他线程不会对容器进行修改,可以避免ConcurrentModificationException。但是在创建副本的时候,存在较大性能开销。

2.并发容器的特性:

  • 根据具体场景进行设计,尽量避免使用锁,提高容器的并发访问性。

  • 并发容器定义了一些线程安全的复合操作。

  • 并发容器在迭代时,可以不封闭在synchronized中。但是未必每次看到的都是”最新的、当前的”数据。如果说将迭代操作包装在synchronized中,可以达到”串行”的并发安全性,那么并发容器的迭代达到了”脏读”。

3.并发容器的分类

  • CopyOnWriteArrayList和CopyOnWriteArraySet分别代替List和Set,主要是在遍历操作为主的情况下来代替同步的List和同步的Set,这也就是上面所述的思路:迭代过程要保证不出错,除了加锁,另外一种方法就是”克隆”容器对象。

  • ConcurrentHashMap是HashMap的线程安全版本

  • ConcurrentSkipListMap是TreeMap的线程安全版本

  • ConcurrentSkipListSet是TreeSet的线程安全版本

  • ConcurrentLinkedQueue是使用非阻塞的方式实现的基于链接节点的无界的线程安全队列,它采用先进先出的规则对节点进行排序,添加元素到队列的尾部;获取元素时返回队列头部的元素。它采用CAS算法实现。

4.阻塞队列

1.一共7个阻塞队列:
(1)ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。

(2)LinkedBlockingQueue :一个由链表结构组成的无界阻塞队列。

  • 构造方法可以设定容量范围。如果未指定容量,则它等于Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。

(3)PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。

  • 调用take方法时才去排序

(4)DelayQueue:一个使用优先级队列实现的无界阻塞队列。

  • 队列中的元素必须实现Delay接口,在创建元素时,可以指定从队列获取元素的限制时长。只有在延迟期满,元素才能被提出队列。

  • 队列中的元素都要延迟时间(超时时间),只有一个元素达到了延时时间才能出队列,也就是说每次从队列中获取的元素总是最先到达延时的元素。

  • 应用场景

    • 缓存系统的设计:可以用DelayQueue保存缓存元素。使用一个线程循环检查队列中的元素,一旦可以从DelayQueue中获取元素时,表示缓存有效期到了。
    • 定时任务调度:使用DelayQueue保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,比如TimeQueue就是使用DelayQueue实现的。

(5)SynchronousQueue:一个不存储元素的阻塞队列。

  • 每个put操作必须等待一个take操作,否则不能继续添加元素

  • SynchronousQueue内部其实没有任何一个元素,容量是0,严格说并不是一种容器。由于队列没有容量,因此不能调用peek操作。因为仅在试图要移除元素时,该元素才存在。除非另一个线程试图移除某个元素,否则也不能(使用任何方法)插入元素;也不能迭代队列,因为其中没有元素可用于迭代。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值