大纲

  1. BlockingQueue接口
  2. ArrayBlockingQueue

一、BlockingQueue接口

public interface BlockingQueue<E> extends Queue<E> {
//add、offer向队列插值,返回插入是否成功
boolean add(E e);
boolean offer(E e);
//向队列插值,队列满则阻塞至队列非满
void put(E e) throws InterruptedException;
//offer方法加上超时,超时返回false
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
//从队列拿值,队列空则阻塞至队列非空
E take() throws InterruptedException;
//向队列拿值,返回是否成功,超时返回false
E poll(long timeout, TimeUnit unit) throws InterruptedException;
//队列剩余空间
int remainingCapacity();
//删除
boolean remove(Object o);
//是否包含
boolean contains(Object o);
//移除队列中的值到集合中
int drainTo(Collection<? super E> c);
//maxElements移除最大个数
int drainTo(Collection<? super E> c, int maxElements);
}

二、ArrayBlockingQueue

主要成员变量

    /** 队列 */
final Object[] items; /** 拿值的索引,用于 take, poll, peek, remove 方法*/
int takeIndex; /** 存值的索引, 用于 next put, offer, or, add 方法*/
int putIndex; /** 队列中元素数量 */
int count; /** 锁,两个condition都是由这个锁创建 */
final ReentrantLock lock; /** 可以拿值的Condition(不空可拿) */
private final Condition notEmpty; /** 可以存值的Condition(不满可存) */
private final Condition notFull;

构造函数

    public ArrayBlockingQueue(int capacity) {
this(capacity, false);
} public ArrayBlockingQueue(int capacity, boolean fair) {
//初始化锁与condition,默认非公平所
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;
//存索引赋值:队列满赋0,不满赋集合数量
putIndex = (i == capacity) ? 0 : i;
} finally {
lock.unlock();
}
}

主要方法

取:

  //非阻塞
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : dequeue();
} finally {
lock.unlock();
}
} //阻塞
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
//队列大小为0拿值线程阻塞
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
//出队
private E dequeue() {
final Object[] items = this.items;
E x = (E) items[takeIndex];
items[takeIndex] = null;
//对应putindex
if (++takeIndex == items.length)
takeIndex = 0;
count--;
if (itrs != null)
itrs.elementDequeued();
//唤醒存值线程
notFull.signal();
return x;
}

存:

//入队
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)
putIndex = 0;
count++;
notEmpty.signal();
}
//非阻塞
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
enqueue(e);
return true;
}
} finally {
lock.unlock();
}
}
//阻塞
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();
}
}

阻塞队列阻塞的存取值方法通过2个condition的await和signal方法完成:当队列空时notEmpty.await取值阻塞,当队列满时notFull.await存值阻塞;入队操作完成时调用notEmpty.signal唤醒取值线程,出队才做完成时唤醒存值线程。

java多线程-阻塞队列BlockingQueue的更多相关文章

  1. Java多线程 阻塞队列和并发集合

    转载:大关的博客 Java多线程 阻塞队列和并发集合 本章主要探讨在多线程程序中与集合相关的内容.在多线程程序中,如果使用普通集合往往会造成数据错误,甚至造成程序崩溃.Java为多线程专门提供了特有的 ...

  2. java 多线程阻塞队列 与 阻塞方法与和非阻塞方法

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  3. Java多线程—阻塞队列和生产者-消费者模式

    阻塞队列支持生产者-消费者这种设计模式.该模式将“找出需要完成的工作”与“执行工作”这两个过程分离开来,并把工作项放入一个“待完成“列表中以便在随后处理,而不是找出后立即处理.生产者-消费者模式能简化 ...

  4. Java并发编程-阻塞队列(BlockingQueue)的实现原理

    背景:总结JUC下面的阻塞队列的实现,很方便写生产者消费者模式. 常用操作方法 常用的实现类 ArrayBlockingQueue DelayQueue LinkedBlockingQueue Pri ...

  5. Java并发(十八):阻塞队列BlockingQueue

    阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用. 阻塞队列常用于生产 ...

  6. Java并发指南11:解读 Java 阻塞队列 BlockingQueue

    解读 Java 并发队列 BlockingQueue 转自:https://javadoop.com/post/java-concurrent-queue 最近得空,想写篇文章好好说说 java 线程 ...

  7. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  8. spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

    一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecut ...

  9. java并发阻塞队列

    Java 并发编程利用 Condition 来实现阻塞队列 You are here:  开发&语言 - Java 文章 发布于 2017年06月26日  阅读 944 并发编程   什么是阻 ...

随机推荐

  1. [GO]panic的应用

    对于异常的处理,error表示的是不太致使的错误,但是如果遇到数组越界或者是空指针这种会导致程序崩溃无法恢复的错误时,就需要使用以panic了 我们不应该使用panic去报error的错误,而是只使用 ...

  2. Git: 教你如何在Commit时有话可说

    Git: 教你如何在Commit时有话可说   不知道大家有没有观察过那些在Github上Star数位居前列的项目,它们无一例外的都拥有完善的文档体系和高覆盖的测试用例.要做到完善没有规范肯定是不行的 ...

  3. HDU 6148 Valley Numer (数位DP)

    题意:... 析:好久没写数位DP了,几乎就是不会了.... dp[i][last][s] 表示前 i 位上一位是 last,当前的状态是 s,0表示非上升,1 表示非下降,然后就很简单了,只有 0 ...

  4. unittest测试框架详谈及实操(四)

    测试套件 应用unittest的Test Suite特性,可以将不同的测试组成一个逻辑组,然后设置统一的测试套来一起执行测试.通过TestSuite.TestLoader类来创建测试套件,最后用Tes ...

  5. 【小梅哥SOPC学习笔记】系统时钟的使用

    给NIOS II CPU添加一颗澎湃的心——系统时钟的使用 本实验介绍如何在Qsys中添加一个定时器作为NIOS II的心跳定时器,并在NIOS II中软件编程使用该定时器. 将上一个实验watchd ...

  6. Git 极简入门教程学习笔记

    Git 极简入门教程  http://rogerdudler.github.io/git-guide/index.zh.html 测试用 https://github.com/xxx/BrnShop. ...

  7. Ray tracing performance benchmark

    accel. avg size 3.14accel. avg depth 16.15accel. max size 8accel. max depth 20accel. GPIT 3.00 MB tr ...

  8. [Perl]Windows 系统 Unicode 文件名操作(新建、重命名、枚举、复制)全攻略

    [Perl] Windows 系统 Unicode 文件名操作(新建.重命名.枚举.复制)全攻略 环境 XP/WIN7 Perl v5.16 编辑整理:PerlMonk.523066680 常见的那些 ...

  9. form表单 相同name 多个value 的后台接受问题

    使用ajax序列化传到后台. data : $("#formid").serialize(); public void fun(@Valid Vo vo){} 使用vo的数组字段属 ...

  10. 设置和获取html、文本和值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...