Queue类及其相关子类

214 阅读1分钟

概述

元素只能从头尾获取,常用于阻塞队列或优先级队列场景使用

Queue

提供了头部取出和尾部插入的操作,基本上没什么人会用抛异常的api

public interface Queue<E> extends Collection<E> {
    # 尾部添加,如果满了就报错
    boolean add(E e);

    # 也是添加操作,队列满了会返回false
    boolean offer(E e);

    # 从头部删除一个元素并返回,如果队列没数据就抛异常
    E remove();

    # 也是从头部删除并返回一个元素,如果没有就返回null
    E poll();

    # 查看头部元素,没有抛异常
    E element();

    # 查看头部元素,没有返回null
    E peek();
}

BlockingQueue

阻塞队列,在多线程同步的场景中很好用

public interface BlockingQueue<E> extends Queue<E> {

    boolean add(E e);

    boolean offer(E e);

    # 往队尾添加元素,如果队列满了就阻塞
    void put(E e) throws InterruptedException;

    # 往队头提取元素,如果队列是空的就阻塞
    E take() throws InterruptedException;

}

ArrayBlockingQueue

我们来看看阻塞队列的具体实现逻辑

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
        implements BlockingQueue<E>, java.io.Serializable {

 
    final Object[] items;

    final ReentrantLock lock;

    # 当前数据量
    int count;

    # 有数据的信号
    private final Condition notEmpty;
    # 有空间的信号
    private final Condition notFull;

    transient Itrs itrs = null;
    


    # 上了一把锁,然后判断数据有没有满,如果满了就阻塞
    public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                notFull.await();
            enqueue(e);
        } finally {
            lock.unlock();
        }
    }

    # 和添加逻辑基本上一样
    public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return dequeue();
        } finally {
            lock.unlock();
        }
    }
}

PriorityQueue

就是在添加的过程中排序,保证顺序性