JUC 之 队列基础篇讲解

JUC 之 队列基础篇讲解

本篇将详细讲解队列的接口实现,为后续篇章的讲解做铺垫。Java 是面向对象的语言,面向对象的原则则是高度抽象,所以我们先来看接口,看看它提供了哪些功能。

Queue 接口

Queue 接口继承自 Collection 接口,说明队列也是一个集合容器,用来存储数据的。通常队列的实现方式为FIFO(先进先出)或 LIFO(后进先出),总是从一头插入一头取数据。下面我们来看看 Queue 额外提供了什么功能。

public interface Queue<E> extends Collection<E> {
    // 向队列中添加元素,成功返回 true,如果队列有容量限制并且队列已满,则抛出IllegalStateException异常。在使用容量受限的队列时,通常建议使用offer。
    boolean add(E e);
    // 向队列中添加元素,成功返回 true,如果队列有容量限制并且队列已满,返回 false
    boolean offer(E e);
    // 从队列头部移除元素,队列为空时抛出异常
    E remove();
    // 从队列头部移除元素,队列为空时返回 null
    E poll();
    // 获取队列头部元素但是不删除,队列为空时抛出异常
    E element();
    // 获取队列头部元素但是不删除,队列为空时返回 null
    E peek();
}

通过上述源码我们看到 Queue 接口只提供了队列基础的添加删除功能。

BlockingQueue 接口

BlockingQueue 接口继承自 Queue 接口,提供队列的阻塞操作功能

public interface BlockingQueue<E> extends Queue<E> {
	// 向队列中添加元素,当队列满时将阻塞等待队列有可用容量
    void put(E e) throws InterruptedException;
	// 向队列中添加元素,成功返回 true,如果队列有容量限制并且队列已满,等待指定时间,如果队列还是没有容量将返回 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();
	// 从队列中移除指定元素
    boolean remove(Object o);
	// 判断队列中是否存在指定元素
    public boolean contains(Object o);
	// 移除队列中所有元素将其添加到指定集合中
    int drainTo(Collection<? super E> c);
	// 从队列中移除指定数量的元素将其添加到给定集合中
    int drainTo(Collection<? super E> c, int maxElements);
}

Deque 接口

Deque 继承自 Queue 接口,支持两端插入或取数据,也即支持双端队列实现。

public interface Deque<E> extends Queue<E> {
    // 向队列头部添加元素
    void addFirst(E e);
    boolean offerFirst(E e);
    // 从队列头部获取元素,队列为空时返回 null
    E pollFirst();
    // 获取队列头部元素,但不从队列中删除,队列为空时抛出异常
    E getFirst();
    // 获取队列头部元素,但不从队列中删除,队列为空时返回 null
    E peekFirst();
    
 	// 向队列尾部添加元素
    void addLast(E e);
    boolean offerLast(E e);
 	// 从队列头部移除元素
    E removeFirst();
	// 从队列尾部移除元素
    E removeLast();
    // 从队列尾部获取元素,队列为空时返回 null
    E pollLast();
    // 获取队列尾部元素,但不从队列中删除,队列为空时抛出异常
    E getLast();
    // 获取队列尾部元素,但不从队列中删除,队列为空时返回 null
    E peekLast();
    
    // *** Stack methods ***
    // 双端队列实现栈
    void push(E e);
    E pop();
}

BlockingDeque 接口

BlockingDeque 继承自 Deque 接口,提供阻塞行为支撑

public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<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;
	// 向队列中添加元素,队列满时阻塞等待,可被中断唤醒
    void put(E e) throws InterruptedException;
	// 从队列头取数据,队列空时阻塞等待,可被中断唤醒
    E take() throws InterruptedException;
}

AbstractQueue 抽象类

采用模板方法设计模式,抽象类提供公共算法实现。

public abstract class AbstractQueue<E> extends AbstractCollection<E> implements Queue<E> {

    // 添加元素实现,调用 offer 方法完成具体添加操作
    public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }
    // 从队列头部移除元素
    public E remove() {
        E x = poll();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }
    // 获取元素实现,具体由 peek 方法实现
    public E element() {
        E x = peek();
        if (x != null)
            return x;
        else
            throw new NoSuchElementException();
    }
    // 清空队列
    public void clear() {
        while (poll() != null)
            ;
    }
	// 将集合中的所有元素添加到队列中,具体添加动作由 add 方法实现
    public boolean addAll(Collection<? extends E> c) {
        if (c == null)
            throw new NullPointerException();
        if (c == this)
            throw new IllegalArgumentException();
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

}

总结:了解了其接口设计和抽象类的实现,下面的篇幅我们将学习具体队列的源码实现,本篇先介绍到这里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值