大纲

  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方法加上超时,超时返回falseboolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;//从队列拿值,队列空则阻塞至队列非空E take() throws InterruptedException;//向队列拿值,返回是否成功,超时返回falseE 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 exclusiontry {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;//对应putindexif (++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唤醒取值线程,出队才做完成时唤醒存值线程。

转载于:https://www.cnblogs.com/liuboyuan/p/10478687.html

java多线程-阻塞队列BlockingQueue相关推荐

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

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

  2. java多线程阻塞队列_阻塞队列和多线程消费者,如何知道何时停止

    我有一个单线程生成器,它创建一些任务对象,然后添加到 ArrayBlockingQueue (具有固定大小) . 我也开始了一个多线程的消费者 . 这是一个固定的线程池( Executors.newF ...

  3. java阻塞队列作用_简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用...

    简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用 Condition:可以理解成一把锁的一个钥匙,它既可以解锁(通知放行),又可以加锁(阻塞) n ...

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

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

  5. java 阻塞队列 BQ_阻塞队列 BlockingQueue的使用(二)

    原 阻塞队列 BlockingQueue的使用(二) BlockingQueue 的核心方法:方法类型抛出异常特殊值阻塞超时 插入add(e)offer(e)put(e)offer(e,time,un ...

  6. Java集合--阻塞队列(ArrayBlockingQueue)

    Java集合–阻塞队列(ArrayBlockingQueue) 1 ArrayBlockingQueue ArrayBlockingQueue是一个阻塞队列,底层使用数组结构实现,按照先进先出(FIF ...

  7. Java集合--阻塞队列(LinkedBlockingQueue)

    Java集合–阻塞队列(LinkedBlockingQueue) 1. LinkedBlockingQueue LinkedBlockingQueue是一个使用链表实现的阻塞队列,支持多线程并发操作, ...

  8. JAVA中阻塞队列的类别和区别(转载)

    这篇文章将介绍什么是阻塞队列,以及Java中阻塞队列的4种处理方式,并介绍Java 7中提供的7种阻塞队列,最后分析阻塞队列的一种实现方式. 阻塞队列(BlockingQueue)是一个支持两个附加操 ...

  9. 并发编程-concurrent指南-阻塞队列BlockingQueue

    阻塞队列BlockingQueue,java.util.concurrent下的BlockingQueue接口表示一个线程放入和提取实例的队列. 适用场景: BlockingQueue通常用于一个线程 ...

最新文章

  1. C++ Const指针学习
  2. Enterprise Library 2.0 技巧(4):如何用编程的方法来配置Logging Application Block
  3. VC++获取屏幕大小第二篇 物理大小GetDeviceCaps 上
  4. 老版本fortran语言 内存无效_编程语言的分类
  5. jzoj4020-Revolution【网络流,最小割】
  6. debian php安装pdo扩展,在debian下为PHP5.0.3安装pdo模块
  7. IDEA的Struts2项目报错java.lang.ClassNotFoundException
  8. python贴吧数据可视化_Python数据可视化
  9. Bean的生命周期简单过程
  10. 如何用英文向论文作者索要源代码--邮件模板
  11. phpQuery采集乱码问题解决方案
  12. C语言求两点之间的距离程序,C语言求空间两点之间的距离
  13. 微信小程序解决 加载图片出现渲染层网络层错误
  14. 还在用QQ邮箱?教你如何创建自己的高逼格邮箱
  15. 网络渗透作业202105110124郭静
  16. SQL进阶教程—自链接的用法
  17. 常见英语面试问答_40个常见的工作面试问答
  18. 科技圈最具权势25大女工程师
  19. 高通AR9344 5.8GHz大功率无线户外CPE
  20. Python术语对照表

热门文章

  1. Yarn基本架构和工作机制
  2. matplotlib画图中文显示
  3. python投资组合
  4. SpringBoot05 数据操作01 - JPA的基本使用、基本使用02
  5. 转Python 标准库 urllib2 的使用细节
  6. Leetcode: Palindrome Numbers
  7. rsyslog+analyzer
  8. 使用NPIO操作Excel
  9. Hibernate的主键生成器generator(zhuan)
  10. 支付宝支付 第九集:产品数据和支付二维码对接