数据结构 - BlockingQueue、BlockingDeque 接口

简介

Queue、Deque 前面已经分析过,它们不是线程安全的,如果非要在多线程中使用Queue或Deque,那么只能把整个队列对象锁住,操作完成在释放锁,这样非常消耗性能,就算多个线程操作不同的元素也要锁整个队列想想都恐怖,有没有更好的办法?JDK中提供了阻塞队列BlockingQueue、BlockingDeque专门用来解决多线程使用队列问题。

BlockingQueue 接口

public interface BlockingQueue<E> extends Queue<E>

BlockingQueue 继承Queue

BlockingQueue 方法

// 添加,满时抛异常
boolean add(E e);
// 添加,满时返回false
boolean offer(E e);
// 添加,满时阻塞
void put(E e) throws InterruptedException;
// 添加,满时阻塞,超时返回false
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
// 出队,空时阻塞
E take() throws InterruptedException;
// 出队,空时阻塞,超时返回null
E poll(long timeout, TimeUnit unit) throws InterruptedException;
// 剩余容量(理想情况下)
int remainingCapacity();
// 删除元素,失败返回false(这里和remove()不一样)
boolean remove(Object o);
// 是否包含
public boolean contains(Object o);
// 从该队列中移除所有可用元素,并将它们添加到给定集合中
int drainTo(Collection<? super E> c);
// 从该队列中移除最多给定数量的可用元素,并将它们添加到给定集合中。
int drainTo(Collection<? super E> c, int maxElements);

BlockingDeque 接口

public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E>

BlockingDeque 继承BlockingQueue 和 Deque 两个接口

BlockingDeque 方法

// 头部添加
void addFirst(E e);
// 尾部添加
void addLast(E e);
// 头部添加
boolean offerFirst(E e);
// 尾部添加
boolean offerLast(E e);
// 头部添加,满时阻塞
void putFirst(E e) throws InterruptedException;
// 尾部添加,满时阻塞
void putLast(E e) throws InterruptedException;
// 头部添加,满时阻塞,超时返回false
boolean offerFirst(E e, long timeout, TimeUnit unit)
        throws InterruptedException;
// 尾部添加,满时阻塞,超时返回false
boolean offerLast(E e, long timeout, TimeUnit unit)
        throws InterruptedException;
// 头部出队,空时阻塞
E takeFirst() throws InterruptedException;
// 尾部出队,空时阻塞
E takeLast() throws InterruptedException;
// 头部出队,空时阻塞,超时返回null
E pollFirst(long timeout, TimeUnit unit)
        throws InterruptedException;
// 尾部出队,空时阻塞,超时返回null
E pollLast(long timeout, TimeUnit unit)
        throws InterruptedException;
// 从头部删除元素
boolean removeFirstOccurrence(Object o);
// 从尾部删除元素
boolean removeLastOccurrence(Object o);
// 添加,满时抛异常
boolean add(E e);
// 添加,满时返回false
boolean offer(E e);
// 添加,满时阻塞
void put(E e) throws InterruptedException;
// 添加,满时阻塞,超时返回false
boolean offer(E e, long timeout, TimeUnit unit)
        throws InterruptedException;
// 出队,空时抛异常
E remove();
// 出队,空时返回null
E poll();
// 出队,空时阻塞
E take() throws InterruptedException;
// 出队,空时阻塞,超时返回null
E poll(long timeout, TimeUnit unit)
        throws InterruptedException;
// 查询,空时异常
E element();
// 查询,空时返回null
E peek();
// 删除元素,空时返回false
boolean remove(Object o);
// 是否包含
public boolean contains(Object o);
// 长度
public int size();
// 迭代器
Iterator<E> iterator();
// 添加,满时抛异常
void push(E e);

阻塞队列扩展非阻塞队列,提供阻塞,阻塞超时等方法。当队列中为空时,从队列中获取元素的操作将被阻塞,当队列满时,向队列中添加元素的操作将被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其它的线程往队列中插入新的元素。同样,试图往满的队列中添加新元素的线程也会被阻塞,直到有其他的线程使队列重新变的空闲起来。

抛出异常:当队列满时,再向队列中插入元素,则会抛出IllegalStateException异常。当队列空时,再向队列中获取元素,则会抛出NoSuchElementException异常。

返回特殊值:当队列满时,向队列中添加元素,则返回false,否则返回true。当队列为空时,向队列中获取元素,则返回null,否则返回元素。

一直阻塞:当阻塞队列满时,如果生产者向队列中插入元素,则队列会一直阻塞当前线程,直到队列可用或响应中断退出。当阻塞队列为空时,如果消费者线程向阻塞队列中获取数据,则队列会一直阻塞当前线程,直到队列空闲或响应中断退出。

超时退出:当队列满时,如果生产线程向队列中添加元素,则队列会阻塞生产线程一段时间,超过指定的时间则退出返回false。当队列为空时,消费线程从队列中移除元素,则队列会阻塞一段时间,如果超过指定时间退出返回null。

posted @ 2020-04-09 12:56  源码猎人  阅读(633)  评论(0编辑  收藏  举报