说起JAVA中的阻塞队列,就不得不提到JAVA中的集合,队列Queue继承了Collection的所有的方法,也是一种集合的表现形式。
下图是java中collection相关的一些接口,主要列出了有关阻塞队列的相关类和接口。
上图总结了常见的集合接口和类的继承和实现关系,用于更清晰把握他们之间的关系和内部实现方式,主要针对于Queue。
下面大致总结一下图中主要类的方法和关系。
Collection && AbstractCollection
1、Collection是接口,包含了操作集合的最基本的方法。AbstractCollection是实现了Collection接口的抽象类,图中ArrayQueue和ConcurrentLinkedDeque就是继承自AbstractCollection抽象类。
2、Collection接口中的方法有:
boolean add(E) , boolean remove(E) ,size(),iterator(),contains(),toArray()等集合最基本的操作方法。
Queue && AbstractQueue
1、Queue是队列集合的接口,继承自Collection接口,除此之外,Queue接口中还增加了一些额外的接口:
- boolean offer(E e); 向队列中添加元素。当队列已满时,则返回false。而add方法当队列已满时会抛出异常,add的内部实现调用的是offer方法。
- E poll(); 删除队列中的第一个元素,当队列为空时返回null,而remove方法则会抛出异常,remove的内部实现调用的是poll方法。
- E element(); 获取队列头部的第一个元素但不删除,当队列为空时会抛出异常,element的内部实现调用的是peek方法。
- E peek(); 获取队列头部的第一个元素但不删除,当队列为空时返回null。
2、AbstractQueue是实现了Queue接口的抽象类。
BlockingQueue
1、BlockingQueue接口是有关阻塞队列的相关接口,它继承自Queue接口。除了Queue中提供有关队列相关的方法外,还额外提供了有关阻塞队列相关的操作方法。
- void put(E e) throws InterruptedException; 向队列中添加一个元素,当队列满时,阻塞,等待队列可用时添加。
- E take() throws InterruptedException; 从队列中取出一个元素,当队列为空时,阻塞,直到队列中有元素时取出。
2、BlockingQueue对应的队列为单向队列,通常指FIFO。
3、BlockingQueue相关的方法都是线程安全的。
小结
下图总结了有关BlockingQueue相关的方法
Deque
1、Deque双端队列接口,继承自Queue接口。既然是双端队列,那么队列的头尾都可以进行进出,所以它还拥有栈的能力。因此,Deque中同时声明了双端队列和栈的实现方法。
其中队列的方法包括(只双端队列):
- void addFirst(E e); 向队列头部添加一个元素。当队列满时,则抛出异常。
- void addLast(E e); 向队列尾部添加一个元素,当队列满时,抛出异常。
- boolean offerFirst(E e); 向队列头部添加一个元素,当队列满时,返回false。
- boolean offerLast(E e); 向队列尾部添加一个元素,当队列满时,返回false。
- E removeFirst(); 移除队列头部的一个元素,当队列为空时,抛出异常。
- E removeLast(); 移除队列尾部一个元素,当队列为空时,抛出异常。
- E pollFirst(); 移除队列头部一个元素,当队列为空时,返回null。
- E pollLast(); 移除队列尾部一个元素,当队列为空时,返回null。
- E getFirst();E getLast();E peekFirst();E peekLast();
栈的操作方法包括:
- void push(E e); 向栈顶压入一个元素,当栈空间满时,抛出异常。
- E pop(); 从栈顶弹出一个元素,当栈为空时,则抛出异常。
2、特殊说明一下,LinkedList类同时实现了Deque和List接口。
BlockingDeque
1、BlockingDeque接口继承了Deque接口和BlockingQueue接口。同时拥有了队列和双端队列以及阻塞队列的方法。相比与Deque和BlockingQueue,增加了以下方法:
- void putFirst(E e) throws InterruptedException; 向队列头部添加一个元素,如果队列满,则阻塞,直到队列可用为止。
- void putLast(E e) throws InterruptedException; 向队列尾部添加一个元素,如果队列满,则阻塞,直到队列可用为止。
- E takeFirst() throws InterruptedException; 从队列头部取出一个元素,当队列为空时阻塞,直到队列中有元素取出成功为止。
- E takeLast() throws InterruptedException; 从队列尾部取出一个元素,当队列为空时阻塞,直到队列中有元素取出成功为止。
2、BlockingDeque也是线程安全的双端队列。
小结
下图总结了有关BlockingDeque相关的方法
ConcurrentLinkedQueue && ConcurrentLinkedDeque
1、故名思议,这两个为线程安全的Queue和Deque。在Queue接口下,BlockingQueue和ConcurrentLinkedQueue是两个线程安全的单向队列,其中BlockingQueue是通过锁实现线程安全的,而concurrentLinkedQueue则是通过CAS来实现线程安全的。
而BlockingDeque和ConcurrentLinkedDeque则是线程安全的双端队列。
2、二者不同的是,ConcurrentLinkedQueue是继承了AbstractQueue接口实现了Queue接口。
而ConcurrentLinkedDeque则是直接实现了Deque的接口,继承了AbstractCollection类。
其实本质都是共用了并且重写了一部分AbstractCollection类中的方法。
以上是对java队列中的各个接口和类的一个总结,接下来的博客会继续总结关于阻塞队列的相关知识。