我们所常用的集合有 List、Set、Map,我们会对集合进行遍历,但是再遍历的过程中不允许对集合进行增删改操作,那么如何再并发环境下操作集合中的数据呢
一、非阻塞式集合(Non-Blocking Collection)
Non-Blocking Collection 这类集合包括添加和移除数据的方法,如果方法不能立即被执行,则返回 null 或抛出异常,但是调用这个方法的线程不会被阻塞
1、ConcurrentLinkedDeque
一个基于链表的无界,**线程安全队列。此队列按照 FIFO**(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许使用 null 元素。
二、阻塞式集合(Blocking Collection)
Blocking Collection 这类集合包括添加和移除数据的方法,当集合已满或者为空的时候。被调用的添加或者移除方法不能立即被执行,那么调用这个方法的线程将会被阻塞,直到成功执行为止
1、ConcurrentHashMap
此类遵守与 Hashtable 相同的功能规范,并且包括对应于 Hashtable 的每个方法的方法版本。不过,尽管所有操作都是线程安全的,但获取操作不 必锁定,并且不 支持以某种防止所有访问的方式锁定整个表。
2、LinkedBlockingDeque
一个基于已链接节点的、任选范围的阻塞双端队列。
如果未指定容量,那么容量将等于 Integer.MAX_VALUE,只要插入元素不会使双端队列超出容量,每次插入后都将动态地创建链接节点。
三、相关方法
| 抛出异常 | 特殊值 | 阻塞 | 超时 | |
|---|---|---|---|---|
| 插入 | add(e) | offer(e) | put(e) | offer(e, time, unit) |
| 移除 | remove() | poll() | take() | poll(time, unit) |
| 检查 | element() | peek() | 不可用 | 不可用 |
1、add & offer & put
- add:增加一个元索至队列的尾部, 如果队列已满,则抛出一个 IIIegaISlabEepeplian 异常
- offer:添加一个元素至队列的尾部,并返回 true,如果队列已满,则返回 false,没有异常
- put:添加一个元素至队列的尾部,如果队列满,则阻塞
2、remove & poll & take
- remove:移除并返回队列头部的元素,如果队列为空,则抛出一个 NoSuchElementException 异常
- poll:移除并返问队列头部的元素,如果队列为空,则返回 null,没有异常
- take:移除并返问队列头部的元素,如果队列为空,则阻塞
3、element & peek
- element:返回队列头部的元素,如果队列为空,则抛出一个NoSuchElementException异常
- peek:返回队列头部的元素,如果队列为空,则返回 null,没有异常
