ArrayBlockingQueue

Posted 学习笔记和总结

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayBlockingQueue相关的知识,希望对你有一定的参考价值。

ArrayBlockingQueue是阻塞队列的一种,基于数组实现,长度固定,队尾添加,队首获取,

 

构造函数:

ArrayBlockingQueue(int capacity)

ArrayBlockingQueue(int capacity, boolean fair)

ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) 

其中capacity为队列的容量,初始化后不可变化。

fair表示多线程操作时是否排队,默认为false,即不保证等待最久的线程优先唤醒。

 

public方法:

boolean add(E e)  在队尾添加,若队列已满则抛出异常,成功返回true

void put(E e)      在队尾添加,成功返回true,队列已满则等待

boolean offer(E e)  在队尾添加,成功返回true,队列已满返回false

boolean offer(E e, long timeout, TimeUnit unit)  在队尾添加,成功返回true,队列已满等待时间为timeout

 

E take()    从队首取元素,如果队列为空,则等待;

E peek()    获取队首元素,若成功,则返回队首元素;否则返回null

E poll()    移除并获取队首元素,若成功,则返回队首元素;否则返回null

E poll(long timeout, TimeUnit unit)         移除并获取队首元素,队列已满等待时间为timeout

 

int size()         返回已使用空间大小

int remainingCapacity()    返回剩余空间大小

boolean remove(Object o)   移除一个equals(o)的元素

boolean contains(Object o)   返回是否包含equals(o)

void clear()  清空队列 

 

实现原理:

--------put

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();
        }
    }
private void enqueue(E x) {
        final Object[] items = this.items;
        items[putIndex] = x;
        if (++putIndex == items.length)
            putIndex = 0;
        count++;
        notEmpty.signal();
    }

--------

首先元素判空,然后获取了单线程可中断锁,然后判断队列是否已满,是则notFull状态等待,否则放入元素并激活等待notEmpty状态的线程,最后解锁。

 

 

 

-------take

public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return dequeue();
        } finally {
            lock.unlock();
        }
    }
private E dequeue() {
        final Object[] items = this.items;
        @SuppressWarnings("unchecked")
        E x = (E) items[takeIndex];
        items[takeIndex] = null;
        if (++takeIndex == items.length)
            takeIndex = 0;
        count--;
        if (itrs != null)
            itrs.elementDequeued();
        notFull.signal();
        return x;
    }

-------

首先获取可中断锁,然后判断队列中是否为空,是则notEmpty状态等待,否则取出元素并激活等待notFull状态的线程,最后解锁。

 

 

 

 

 

一个例子:

------

------

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

以上是关于ArrayBlockingQueue的主要内容,如果未能解决你的问题,请参考以下文章

ArrayBlockingQueue图解源码分析

并发容器之ArrayBlockingQueue与LinkedBlockingQueue详解

ArrayBlockingQueue源码阅读(1.8)

线程池阻塞队列之ArrayBlockingQueue

并发队列之ArrayBlockingQueue

死磕 java集合之ArrayBlockingQueue源码分析