我理解的Java并发基础(六):并发容器和队列

J.U.C包含许多并发经常使用的容器类工具,好比ConcurrentHashMap、CopyOnWriteArrayList。由与队列Queue在并发中很是重要,而且种类很是多,故本文将队列单独列出,不计算在容器类中。java

1,ConcurrentHashMap,并发Map。并发编程中最经常使用的并发容器。JDK1.8中的底层实现与以前版本不一样。在API的使用上和java.lang.HashMap相同。须要注意的是,HashMap支持null做为key,而ConcurrentHashMap不支持,会报空指针异常。ConcurrentHashMap在遍历的时候没有FailFast机制。编程

2,CopyOnWriteArrayList,支持并发读写的List。在API的使用上和java.lang.ArrayList相同。容许一个线程写的同时多个线程进行读操做。CopyOnWriteArrayList在遍历的时候没有FailFast机制。数组

队列是并发中常常出现的结构。队列包括阻塞队列BlockingQueue、双端阻塞队列BlockingDequeue、并发队列(非阻塞)ConcurrentLinkedQueue等。遵循FIFO先入先出的原则。安全

BlockingQueue接口的经常使用API以下:并发

boolean add(E e); // 增长元素。若是队列已满,抛IllegalStateException异常
void put(E e) throws InterruptedException; // 增长元素。若是队列已满,则阻塞等待。阻塞期间响应线程中断异常。
boolean offer(E e); // 增长元素。若是队列已满,直接返回false。
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException // 增长元素。若是队列已满,则阻塞等待一段时间。阻塞期间响应线程中断异常。返回值同offer(E e)

boolean remove(Object o); // 删除指定元素。若是队列发生了改变,则返回true。
E take() throws InterruptedException; // 获取元素。若是队列为空则阻塞等待。阻塞期间响应线程中断异常。
E poll(long timeout, TimeUnit unit) throws InterruptedException; // 指定时间内阻塞等待获取元素。若是队列为空则阻塞等待。阻塞期间响应线程中断异常。
boolean contains(Object o); // 队列中是否包含指定元素

int remainingCapacity(); // 队列还能存放多少个元素,返回值 = 初始化总数 - 以存放个数

BlockingQueue接口的实现类有:ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue。工具

1,ArrayBlockingQueue,数组阻塞队列。ArrayBlockingQueue 是一个有界的阻塞队列,构造方法能够指定是不是公平性。其内部实现是将对象放到一个数组里。有界也就意味着,它不可以存储无限多数量的元素。它有一个同一时间可以存储元素数量的上限。你能够在对其初始化的时候设定这个上限,但以后就没法对这个上限进行修改了 (译者注:由于它是基于数组实现的,也就具备数组的特性:一旦初始化,大小就没法修改)。ArrayBlockingQueue 内部以 FIFO(先进先出)的顺序对元素进行存储。队列中的头元素在全部元素之中是放入时间最久的那个,而尾元素则是最短的那个。线程

2,DelayQueue,延迟队列。DelayQueue 对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现java.util.concurrent.Delayed接口。给接口继承了java.lang.Comarable比较器接口,具体以下:指针

public interface Delayed extends Comparable<Delayed> {
    long getDelay(TimeUnit unit);
}

DelayQueue 将会在每一个元素的getDelay()方法返回的值的时间段以后才加入到队列中。若是返回的是 0 或者负值,则直接加入到队列中。code

3,LinkedBlockingQueue,链表阻塞队列。LinkedBlockingQueue是效率最高的、出镜率最高的阻塞队列,内部以一个链式结构(连接节点)对其元素进行存储。若是须要的话,这一链式结构能够选择一个上限。若是没有定义上限,将使用 Integer.MAX_VALUE 做为上限。对象

4,PriorityBlockingQueue,优先级队列。PriorityBlockingQueue是一个无界的并发队列。它使用了和ava.util.PriorityQueue 同样的排序规则。全部插入到 PriorityBlockingQueue 的元素必须实现java.lang.Comparable接口,由于元素的优先级比较是经过Comparable接口来完成的。列中元素的排序就取决于你本身的 Comparable 实现。tips:从PriorityBlockingQueue队列返回的Iterator并不能保证元素的遍历是元素的优先级顺序的。

5,SynchronousQueue,同步队列。SynchronousQueue是一个特殊的队列,它的内部同时只可以容纳1个元素。若是该队列已 有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另外一个线程将该元素从队列中抽走。一样,若是该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另外一个线程向队列中插入了一条新的元素。

6,LinkedTransferQueue,无界链表队列。相比于LinkedBlockingQueue,多了tryTransfer和transfer方法。

void transfer(E e) throws InterruptedException // 若是有线程在阻塞等待回去元素,则直接将e传递给等待的线程。若是没有则阻塞等待线程来获取元素。阻塞期间响应线程中断异常。(违反了FIFO原则)
boolean tryTransfer(E e, long timeout, TimeUnit unit)throws InterruptedException // 一段时间内阻塞等待线程获取元素,做用同transfer(E e)。若是超时则返回false。

BlockingDeque是双端阻塞队列接口,容许在队列的两端进元素进行添加和获取。继承类BlockingQueue接口,可是不推荐使用BlockingQueue相关的API。BlockingDeque的经常使用API以下:

//在头部操做
boolean addFirst(E e); // 同BlockingQueue的add(E e)
void putFirst(E e) throws InterruptedException; // 同BlockingQueue的put(E e)
boolean offerFirst(E e); // 同BlockingQueue的offer(E e)
boolean offerFirst(E e, long timeout, TimeUnit unit) throws InterruptedException // 同BlockingQueue的offer(E e, long timeout, TimeUnit unit)
boolean removeFirstOccurrence(Object o); // 从头部开始删除第一个相同的元素。同BlockingQueue的remove(E e)
E takeFirst() throws InterruptedException; // 同BlockingQueue的take()
E pollFirst(long timeout, TimeUnit unit) throws InterruptedException; // 同BlockingQueue的poll()


// 在尾部操做
boolean addLast(E e); // 同BlockingQueue的add(E e)
void putLast(E e) throws InterruptedException; // 同BlockingQueue的put(E e)
boolean offerLast(E e); // 同BlockingQueue的offer(E e)
boolean offerLast(E e, long timeout, TimeUnit unit) throws InterruptedException // 同BlockingQueue的offer(E e, long timeout, TimeUnit unit)
boolean removeLastOccurrence(Object o); // 从尾部开始删除第一个相同的元素。同BlockingQueue的remove(E e)
E takeLast() throws InterruptedException; // 同BlockingQueue的take()
E pollLast(long timeout, TimeUnit unit) throws InterruptedException; // 同BlockingQueue的poll()

7,LinkedBlockingDeque,链表双端阻塞队列。J.U.C包中BlockingDeque接口的惟一实现类。其实现与LinkedBlockingQueue相同。当链表为空的时候,一个试图从中抽取数据的线程将会阻塞,不管该线程是试图从哪一端抽取数据。建议使用Deque进行多态形式的API操做。

8,ConcurrentLinkedQueue,并发非阻塞安全队列。ConcurrentLinkedQueue实现了Queue接口,是一个基于链表的无界队列,遵循FIFO先进先出原则,使用循环CAS的方式来实现非阻塞并发安全。建议使用Queue进行多态形式的API操做。

相关文章
相关标签/搜索