笔记:多线程-集合
- 阻塞队列(BlockingQueue)
当试图向队列添加元素而队列已满,或是想从队列移除元素而队列为空的时候,阻塞队列导致线程阻塞,阻塞队列接口定义如下,他继承Queue<E>接口:
public interface BlockingQueue<E> extends Queue<E> {
/**
* 添加一个元素,如果队列满,则抛出 IllegalStateException异常
*/
boolean add(E e);
/**
* 添加一个元素并返回 true,如果队列满,则返回 false
*/
boolean offer(E e);
/**
* 添加一个元素并返回 true,如果队列满或者在达到超时时间后返回 false
* @param e 新添加元素
* @param timeout 超时时间
* @param unit 超时时间单位
* @return 添加一个元素并返回 true,如果队列满或者在达到超时时间后返回 false
* @throws InterruptedException
*/
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 添加一个元素,如果队列满则阻塞线程
* @throws InterruptedException
*/
void put(E e) throws InterruptedException;
/**
* 移除并返回头元素,如果队列为空,则阻塞线程
* @return
* @throws InterruptedException
*/
E take() throws InterruptedException;
/**
* 移除并返回队列的头元素,如果队列为空或者达到超时时间则返回null
* @param timeout 超时时间
* @param unit 超时时间单位
* @return 移除并返回队列的头元素,如果队列为空或者达到超时时间则返回null
* @throws InterruptedException
*/
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
}
阻塞队列的Java实现类有LinkedBlockingQueue(链表阻塞队列)、LinkedBlockingDeque(双链表阻塞队列)、ArrayBlockingQueue(数组阻塞队列)、PriorityBlockingQueue(优先级阻塞队列),根据底层数据结构可以得知LinkedBlockingQueue和LinkedBlockingDeque链表数据结构的容量是没有上边界的,但是可以选择指定最大容量;ArrayBlockingQueue数组在构造时需要指定容量,并且有一个可选择参数,是否需要开启公平性,如果开启,则会等待了最长时间的线程优先处理;PriorityBlockingQueue是一个带优先级的队列,而不是先进先出的,元素按照他们的优先顺序被移除,该队列没有容量上限。
- 高效的映射表、集合和队列
这些集合采用复杂的算法,通过允许并发访问数据结构的不同部分来使竞争极小化,其size方法不是常量时间,而是需要进行遍历,集合返回弱一致性迭代器,并不会抛出 ConcurrentModificationException 异常
- ConcurrentHashMap和 ConcurrentSkipListMap
需要使用原子性的关联插入及关联删除,putIfAbsent 方法会查询是否存在Key,如果不存在自动的增加新关联并返回 null,存在则返回已经存在的值;remove 将原子性的删除键值对。
- ConcurrentSkipListSet
- ConcurrentLInkedQueue
其操作和非线程安全的集合和队列是一致的