java多线程-阻塞队列BlockingQueue
大纲
- BlockingQueue接口
- 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相关推荐
- java 多线程阻塞队列 与 阻塞方法与和非阻塞方法
Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...
- java多线程阻塞队列_阻塞队列和多线程消费者,如何知道何时停止
我有一个单线程生成器,它创建一些任务对象,然后添加到 ArrayBlockingQueue (具有固定大小) . 我也开始了一个多线程的消费者 . 这是一个固定的线程池( Executors.newF ...
- java阻塞队列作用_简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用...
简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用 Condition:可以理解成一把锁的一个钥匙,它既可以解锁(通知放行),又可以加锁(阻塞) n ...
- Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例
Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...
- java 阻塞队列 BQ_阻塞队列 BlockingQueue的使用(二)
原 阻塞队列 BlockingQueue的使用(二) BlockingQueue 的核心方法:方法类型抛出异常特殊值阻塞超时 插入add(e)offer(e)put(e)offer(e,time,un ...
- Java集合--阻塞队列(ArrayBlockingQueue)
Java集合–阻塞队列(ArrayBlockingQueue) 1 ArrayBlockingQueue ArrayBlockingQueue是一个阻塞队列,底层使用数组结构实现,按照先进先出(FIF ...
- Java集合--阻塞队列(LinkedBlockingQueue)
Java集合–阻塞队列(LinkedBlockingQueue) 1. LinkedBlockingQueue LinkedBlockingQueue是一个使用链表实现的阻塞队列,支持多线程并发操作, ...
- JAVA中阻塞队列的类别和区别(转载)
这篇文章将介绍什么是阻塞队列,以及Java中阻塞队列的4种处理方式,并介绍Java 7中提供的7种阻塞队列,最后分析阻塞队列的一种实现方式. 阻塞队列(BlockingQueue)是一个支持两个附加操 ...
- 并发编程-concurrent指南-阻塞队列BlockingQueue
阻塞队列BlockingQueue,java.util.concurrent下的BlockingQueue接口表示一个线程放入和提取实例的队列. 适用场景: BlockingQueue通常用于一个线程 ...
最新文章
- C++ Const指针学习
- Enterprise Library 2.0 技巧(4):如何用编程的方法来配置Logging Application Block
- VC++获取屏幕大小第二篇 物理大小GetDeviceCaps 上
- 老版本fortran语言 内存无效_编程语言的分类
- jzoj4020-Revolution【网络流,最小割】
- debian php安装pdo扩展,在debian下为PHP5.0.3安装pdo模块
- IDEA的Struts2项目报错java.lang.ClassNotFoundException
- python贴吧数据可视化_Python数据可视化
- Bean的生命周期简单过程
- 如何用英文向论文作者索要源代码--邮件模板
- phpQuery采集乱码问题解决方案
- C语言求两点之间的距离程序,C语言求空间两点之间的距离
- 微信小程序解决 加载图片出现渲染层网络层错误
- 还在用QQ邮箱?教你如何创建自己的高逼格邮箱
- 网络渗透作业202105110124郭静
- SQL进阶教程—自链接的用法
- 常见英语面试问答_40个常见的工作面试问答
- 科技圈最具权势25大女工程师
- 高通AR9344 5.8GHz大功率无线户外CPE
- Python术语对照表