ArrayBlockingQueue

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

构造函数:

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

ArrayBlockingQueue(int capacity)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

ArrayBlockingQueue(int capacity, boolean fair)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

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

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

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

public方法:

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }

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

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

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #7e504f }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }
span.s1 { color: #931a68 }
span.s2 { color: #7e504f }

时间: 2024-10-01 03:04:49

ArrayBlockingQueue的相关文章

ArrayBlockingQueue源码分析

转自:http://www.xiaoyaochong.net/wordpress/?p=354 ArrayBlockingQueue是Java并发框架中阻塞队列的最基本的实现,分析这个类就可以知道并发框架中是如何实现阻塞的. 笔者工作了一两年之后,还不知道阻塞是如何实现的,当然有一个原因是前期学习的东西比较杂,前后端的东西的懂一点,但是了解的不够深刻,我觉得这是编程学习的禁忌,不管是前端还是后端,在工作3年的时候,你应该有一个方向是拿得出手,见得了人的. 转回整体,ArrayBlockingQu

Java多线程-新特征-阻塞队列ArrayBlockingQueue

阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止.同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元素为止. 有了这样的功能,就为多线程的排队等候的模型实现开辟了便捷通道,非常有用. java.util.concurrent.BlockingQueue继承了java.util.Queue接口,可

深入剖析java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue

关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入理解Java并发之synchronized实现原理 Java并发编程-无锁CAS与Unsafe类及其并发包Atomic 深入理解Java内存模型(JMM)及volatile关键字 剖析基于并发AQS的重入锁(ReetrantLock)及其Condition实现原理 剖析基于并发AQS的共

ArrayBlockingQueue和LinkedBlockingQueue分析

一.BlockingQueue接口       BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞. 二.ArrayBlockingQueue      ArrayBlockingQueue是一个由数组支持的有界阻塞队列.在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式. 三.LinkedBlock

Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过start方法启动线程--->线程变为可运行可执行状态,然后通过数据产生共享,线程产生互斥---->线程状态变为阻塞状态---->阻塞状态想打开的话可以调用notify方法. 这里Java5中提供了封装好的类,可以直接调用然后构造阻塞状态,以保证数据的原子性. 2.如何实现? 主要是实现Blo

BlockQueue中ArrayBlockingQueue和LinkedBlockingQueue比较

LinkedBlockingQueue是BlockingQueue的一种使用Link List的实现,它对头和尾(取和添加操作)采用两把不同的锁,相对于ArrayBlockingQueue提高了吞吐量.它也是一种阻塞型的容器,适合于实现"消费者生产者"模式. ArrayBlockingQueue是对BlockingQueue的一个数组实现,它使用一把全局的锁并行对queue的读写操作,同时使用两个Condition阻塞容量为空时的取操作和容量满时的写操作. 正因为LinkedBlock

java 阻塞队列 LinkedBlockingQueue ArrayBlockingQueue 分析

BlockingQueue是阻塞队列接口类,该接口继承了Queue接口 BlockingQueue实现类常见的有以下几种. ArrayBlockingQueue:ArrayBlockingQueue 是一个有界的阻塞队列,其内部实现是将对象放到一个数组里.有界也就意味着,它不能够存储无限多数量的元素.它有一个同一时间能够存储元素数量的上限.你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了(译者注:因为它是基于数组实现的,也就具有数组的特性:一旦初始化,大小就无法修改). D

《java.util.concurrent 包源码阅读》06 ArrayBlockingQueue

对于BlockingQueue的具体实现,主要关注的有两点:线程安全的实现和阻塞操作的实现.所以分析ArrayBlockingQueue也是基于这两点. 对于线程安全来说,所有的添加元素的方法和拿走元素的方法都会涉及到,我们通过分析offer方法和poll()方法就能看出线程安全是如何实现的. 首先来看offer方法 public boolean offer(E e) { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lo

ArrayBlockingQueue,BlockingQueue分析

BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞. ArrayBlockingQueue是一个由数组支持的有界阻塞队列.在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式. 基于链表的阻塞队列,同ArrayBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),当生产

ArrayBlockingQueue和LinkedBlockingQueue

1. ArrayBlockingQueue 数组存储,固定大小的队列. 一个items数组,一个putIndex指针,从0到len代表已经入队了多少个元素.一个takeIndex指针,从0到len代表出队的元素位置.一个count,记录当前队列里有多少元素. putIndex指针入队的时候不断++,takeIndex出队的时候不断++.这个队列不是一个循环队列,判断队列空和满用count和items.length比较. 入队: 内部的lock锁定,如果队列满,sleep等待,当可以插入的时候,i