JAVA的Queue接口,阻塞与非阻塞队列,以及阻塞实现原理

Queue接口与List、Set同一级别,都是继承了Collection接口。
集合框架包含的内容
这里写图片描述
Queue的实现
阻塞的意思是如果队满加入或者对空输出都是需要需要等待
而非阻塞的并不用。
一.Queue的实现
1.没有实现阻塞接口的:
(1)LinkedList :
实际是双向链表 实现了 Deque 接口最实用(也是一个最常用的Queue的实现型)
(2)PriorityQueue:
从小到大排序好的列表 逻辑结构是一棵完全二叉树另一篇文章会写 (需要java.util.Comparable)
(3)ConcurrentLinkedQueue:
是一个线程安全的并发不需要同步的线程。
2.实现阻塞的接口:
(1)ArrayBlockingQueue
一个由数组支持的有界队列。
(2)LinkedBlockingQueue
一个由链接节点支持的可选有界队列。
(3)PriorityBlockingQueue
一个由优先级堆支持的无界优先级队列。
(4)DelayQueue
一个由优先级堆支持的,基于时间的调度队列。
(5)SynchronousQueue
一个利用BlockingQueue接口的简单聚集(rendezvous)机制
二.阻塞和非阻塞的区别
1.非阻塞队列中的几种主要方法:
add(E e) : 将元素e插入到队列末尾,如果插入成功,则返回true;如果插入失败(即队列已满),则会抛出异常;
remove() :移除队首元素,若移除成功,则返回true;如果移除失败(队列为空),则会抛出异常;
offer(E e) :将元素e插入到队列末尾,如果插入成功,则返回true;如果插入失败(即队列已满),则返回false;
poll() :移除并获取队首元素,若成功,则返回队首元素;否则返回null;
peek() :获取队首元素,若成功,则返回队首元素;否则返回null

对于非阻塞队列,一般情况下建议使用offer、poll和peek三个方法,不建议使用add和remove方法。因为使用offer、poll和peek三个方法可以通过返回值判断操作成功与否,而使用add和remove方法却不能达到这样的效果。注意,非阻塞队列中的方法都没有进行同步措施。

2.阻塞的队列方法
put(E e) : 用来向队尾存入元素,如果队列满,则等待;
take() : 用来从队首取元素,如果队列为空,则等待;
offer(E e,long timeout, TimeUnit unit) : 用来向队尾存入元素,如果队列满,则等待一定的时间,当时间期限达到时,如果还没有插入成功,则返回false;否则返回true;
poll(long timeout, TimeUnit unit) : 用来从队首取元素,如果队列空,则等待一定的时间,当时间期限达到时,如果取到,则返回null;否则返回取得的元素;

三.阻塞实现原理
ArrayBlockingQueue中实现的方法

 /** Main lock guarding all access */
final ReentrantLock lock;
/** Condition for waiting takes */
private final Condition notEmpty;
/** Condition for waiting puts */
private final Condition notFull;

public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
        throw new IllegalArgumentException();
    this.items = new Object[capacity];
    lock = new ReentrantLock(fair);
    notEmpty = lock.newCondition();
    notFull =  lock.newCondition();
}

public ArrayBlockingQueue(int capacity, boolean fair,
                         Collection<? extends E> c) {
    this(capacity, fair);

    final ReentrantLock lock = this.lock;
    lock.lock(); // Lock only for visibility, not mutual exclusion
    try {
        int i = 0;
        try {
            for (E e : c) {
                checkNotNull(e);
                items[i++] = e;
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            throw new IllegalArgumentException();
        }
        count = i;
        putIndex = (i == capacity) ? 0 : i;
    } finally {
        lock.unlock();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42166409/article/details/81481212