大纲

  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. 为啥final类型的map或者arraylist可以修改数据 而final类型的String变量不可以修改数据呢

    比如 final   Map  map =new  HashMap();    可以往map里put数据final   List  list =new  ArrayList();   可以往list里 ...

  2. 说说JVM中的操作码

    JVM操作码 加载与存储操作码 load --从局部变量加载值到栈上 ldc --从池中加载常量到栈上 store --把值从栈中移走,存到局部变量中 dup --复制栈顶的值 getField -- ...

  3. unity小记

    1.window下的Occlusion Culling是实现遮挡剔除效果,即不再摄像机里出现的物体使其不被渲染. 这样做要使物体为静态的,而且效果在设计时只在Occlusion面板下有效 2.wind ...

  4. 软件加license的一种实现方法

    以前从没干过破解的勾当,这次确实必须要去破解一个,于是下了个反编译工具. 最终拿到反编译出来的文件,欣赏了一把它的license检测代码.原谅我的无知,以下代码在我看来还是比较新鲜,犬神请不要鄙视: ...

  5. [Delphi] Webbroker ISAPI 示例说明

    新建Webbroker项目: 选择类型: 开始可以使用:Indy VCL Application 方便调试,完成后,再新建一个DLL 项目,引用业务单元.   示例代码如下: unit uDataMo ...

  6. python版本selenium定位方式(不止八种哦)

    除了大家熟知的8种定位方式之外 1.id定位:find_element_by_id(self, id_)2.name定位:find_element_by_name(self, name)3.class ...

  7. C# winfrom 存取图片到数据库(二进制,image)

    1.读取本地图片到PictureBox public void InageShow(PictureBox PB) { OpenFileDialog openfile = new OpenFileDia ...

  8. python,使用百度api实现复制截图中的文字

    百度云文字识别技术文档: 跳转 第三方模块安装: pip install baidu-aip pip install Pillow pip install keyboard pip install p ...

  9. 二十、Node.js- WEB 服务器 (三)静态文件托管、 路 由

    1.Nodejs 静态文件托管 上一讲的静态 web 服务器封装 项目结构: Web服务器封装成的模块:router.js代码: var http=require('http'); var fs=re ...

  10. Django-01Django简介

    1 MVC与MTV模型 MVCWeb服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负责业 ...