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状态的线程,最后解锁。

其他阻塞队列:

----------------------------

//链表实现的队列,动态大小

BlockingQueue<String> queue2 = new LinkedBlockingQueue<String>();

//有优先级的阻塞队列

BlockingQueue<String> queue3 = new PriorityBlockingQueue();

//队列中只能有一个元素

BlockingQueue<String> queue4 = new SynchronousQueue();

---------------------------

一个例子:

------

------

1





ArrayBlockingQueue的更多相关文章

  1. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  2. 阅读ArrayBlockingQueue源码了解如何利用锁实现BlockingQueue

    BlockingQueue是多线程里面一个非常重要的数据结构.在面试的时候,也常会被问到怎么实现BlockingQueue.本篇根据Java7里ArrayBlockingQueue的源码,简单介绍一下 ...

  3. JAVA可阻塞队列-ArrayBlockingQueue子类BlockingQueue的应用,使用它来实现子线程打印10次,主线程打印100次,如此反复

    /** * 使用BlockingQueue实现主子线程互相打印 * @author duwenlei * */ public class BlockingQueueTest { public stat ...

  4. JAVA可阻塞队列-ArrayBlockingQueue

    在前面的的文章,写了一个带有缓冲区的队列,是用JAVA的Lock下的Condition实现的,但是JAVA类中提供了这项功能,就是ArrayBlockingQueue, ArrayBlockingQu ...

  5. Java多线程系列--“JUC集合”07之 ArrayBlockingQueue

    概要 本章对Java.util.concurrent包中的ArrayBlockingQueue类进行详细的介绍.内容包括:ArrayBlockingQueue介绍ArrayBlockingQueue原 ...

  6. Java并发之BlockingQueue 阻塞队列(ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue、PriorityBlockingQueue、SynchronousQueue)

    package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Create ...

  7. ArrayBlockingQueue跟LinkedBlockingQueue的区别

    .队列中的锁的实现不同 ArrayBlockingQueue中的锁是没有分离的,即生产和消费用的是同一个锁: LinkedBlockingQueue中的锁是分离的,即生产用的是putLock,消费是t ...

  8. ArrayBlockingQueue,BlockingQueue分析

    BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会 ...

  9. ArrayBlockingQueue-我们到底能走多远系列(42)

    我们到底能走多远系列(42) 扯淡: 乘着有空,读些juc的源码学习下.后续把juc大致走一边,反正以后肯定要再来. 主题: BlockingQueue 是什么 A java.util.Queue t ...

随机推荐

  1. java 通过控制台输入的数字打印菱形字母

    package com.rui.test; import java.util.Scanner; /** * @author sunshine * @version 1.0 * @date:2015年1 ...

  2. java读取属性配置文件工具类

    import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * * 类: ProU ...

  3. MySQL 5.7贴心参数之binlog_row_image

    相信大家都了解mysql binlog的格式,那就是有三种,分别是STATEMENT,MiXED,ROW.各有优劣,具体的请大家自行查阅资料.在MySQL 5.7版本以前,虽然ROW格式有各种各样的好 ...

  4. hdu1201-18岁生日

    Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所以他想请你帮忙计算一下他和他的几个朋友从 ...

  5. 如何使用 vimdiff 来 git diff /svn diff

    #git 如何实现vimdiffgit config --global diff.tool vimdiff git config --global difftool.prompt false git ...

  6. 一个相比jdk的io包更方便处理数据读写的包

    apche的commons-io.jar包,里面有个类IOUtils,提供的下列方法: readLines方法能够从字节输入流或字符输入流里读取数据,按行读,返回字符串组成的list write方法能 ...

  7. LoadRunner,一个简单的例子

    一.录制脚本,这个就不说了,但是可以说说录完一个简单的脚本之后可以做的一些后续工作 1.设置事务的开始跟结束点(参考他人的http://www.cnblogs.com/fnng/archive/201 ...

  8. 解决git .ignore文件无效

    在用 Git 进行代码管理的时候,我们会用 .gitignore 文件来描述哪些文件是不需要进行版本管理的,也就是被忽略掉. 如果我们在第一次提交的时候,忘记添加 .gitignore 文件或者在首次 ...

  9. Ubuntu 14.04 升级gcc 4.8到gcc 5.x

    简介 有些软件比较新,需要更高的gcc版本,所以需要升级gcc.编译安装比较耗时,所以直接选择bin包就好. 步骤 添加源 sudo add-apt-repository ppa:ubuntu-too ...

  10. 详解php的curl几个函数

    关于php的curl一系列函数,这里解释一下它们的作用. 在html中,我们可以通过form设置http的post和get提交,但假如我们获取的数据不是从html中来的,而是php脚本主动向其他服务器 ...