回顾:

阻塞队列,英文名叫BlockingQueue。首先他是一种队列,联系之前Java基础——集合中介绍的Queue与Collection,我们就很容易开始今天的阻塞队列的学习了。来看一下他们的接口定义:

Queue:

(方法很简单,就不一一注释解释其作用了。)

public interface Queue<E> extends Collection<E> {

    boolean add(E e);

    boolean offer(E e);

    E remove();

    E poll();

    E element();

    E peek();
}

BlockingQueue:

因为是继承自Queue,方法基本类似,就不再写了。主要方法有三个:add,remove,element(用于检查)。

那到底什么是阻塞队列呢?联系前面java线程——模拟生产者与消费者的例子,在篮子中没有馒头时,生成者要放入馒头消费者才能食用;在篮子里装满馒头时,生产者就不能继续生产了,要等人去吃。阻塞队列就是生产者存放馒头的容器,消费者从中取出元素,也就是那个篮子。

public interface BlockingQueue<E> extends Queue<E> {
......
}

BlockingQueue的实现类有很多,这里介绍一个很简单的ArrayBlockingQueue。他是一个数据结构组成的阻塞队列,按照FIFO先进先出的方式排序。

继续来看他的定义,下面只列举了常用的两个方法:

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable { //放入元素
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();
}
} //取元素
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
}
}
}

来个例子:

//Capacity为3的阻塞队列
final BlockingQueue queue = new ArrayBlockingQueue(3);
for (int i = 0; i < 2; i++) {
//1、放馒头线程
new Thread() { @Override
public void run() {
while (true) { try {
Thread.sleep((long) (Math.random() * 10000));
System.out.println(Thread.currentThread().getName()
+ "准备放馒头!");
//每次放入一个馒头
queue.put(1);
System.out.println(Thread.currentThread().getName()
+ "已经放了馒头," + "队列目前有" + queue.size()
+ "个馒头");
} catch (InterruptedException e) { e.printStackTrace();
}
}
} }.start();
}
//2、取馒头线程
new Thread() { @Override
public void run() {
while (true) {
try { Thread.sleep((long) (Math.random() * 10000));
System.out.println(Thread.currentThread().getName()
+ "准备取馒头!");
//拿走一个
queue.take();
System.out.println(Thread.currentThread().getName()
+ "已经取走馒头," + "队列目前有" + queue.size() + "个馒头");
} catch (InterruptedException e) { e.printStackTrace();
}
}
} }.start(); }

部分执行结果:

对比:

和之前手动实现生产者消费者的例子相比,这次的实现就简单多了。不再需要去管篮子里的“取”和“放”的操作,不用关心线程的同步互斥问题,不用关心篮子是空了还是满了。只需要简单的调用put或take方法即可,把复杂的阻塞问题教给BlockingQueue去处理,但是原理还是一样的。

java线程(7)——阻塞队列BlockingQueue的更多相关文章

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

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

  2. java并发包——阻塞队列BlockingQueue及源码分析

    一.摘要 BlockingQueue通常用于一个线程在生产对象,而另外一个线程在消费这些对象的场景,例如在线程池中,当运行的线程数目大于核心的线程数目时候,经常就会把新来的线程对象放到Blocking ...

  3. Java并发编程——阻塞队列BlockingQueue

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

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

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

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

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

  6. java线程自带队列的使用以及线程阻塞

    java线程,设置队列的大小实现队列阻塞 public class QueueThreads { private static int nThreads = 4;//Runtime.getRuntim ...

  7. Java中的阻塞队列(BlockingQueue)

    1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...

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

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

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

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

  10. Java中的阻塞队列

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

随机推荐

  1. HDU 6330--Visual Cube(构造,计算)

    Visual Cube 将这个立方体分块,分成上中下三个部分,利用长宽高计算行列,最后输出即可. 每个部分都分成奇偶行来输出,总共有\(2*(b+c)+1\)行,共\(2*(a+b)+1\)列.设当前 ...

  2. Keepalived 配置高可用

    VRRP协议及Keepalived原理使用   VRRP 协议即 Virtual Router Redundancy Protocol,虚拟路由器冗余协议, 为了解决局域网内默认网关单点失效的问题.  ...

  3. 构建高可靠hadoop集群之2-机栈

    本文主要参考 http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-common/RackAwareness.html had ...

  4. CodeTimer 代码性能计数器

    收集整理老赵 的”CodeTimer“. 用于测试代码性能.详见可参考 老赵原文 代码如下: using System; using System.Diagnostics; using System. ...

  5. 关于Ext.js和Ext.Net的杂谈

    最近几年比较火的前端js框架extjs 算是其中的佼佼者.统一的UI设计,强悍的组件及丰富的插件,对浏览器良好的兼容性等优点使得许多公司使用Extjs,同时也使得无数程序猿开始研究这个玩意也包括我在内 ...

  6. Java 使用Apache POI读取和写入Excel表格

    1,引入所用的包 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxm ...

  7. 数据解压及if else的应用

    def sum(items): head, *tails = items return head + sum(tails) if tails else head # 最后一句有点像三目运算符,如果ta ...

  8. 13.6 模拟事件【JavaScript高级程序设计第三版】

    事件,就是网页中某个特别值得关注的瞬间.事件经常由用户操作或通过其他浏览器功能来触发. 但很少有人知道,也可以使用JavaScript 在任意时刻来触发特定的事件,而此时的事件就如同浏览器创建的事件一 ...

  9. Python正则表达式-基础

    Python正则表达式-基础 本文转载自昔日暖阳,原文地址:http://www.osheep.cn/4806.html python使用正则,需要先引入re模块 import re 匹配符 单个字符 ...

  10. jenkins邮件发送jmeter接口测试报告

    在Jenkins中配置实现邮件通知,Jenkins提供了两种方式的配置. 一种是Jenkins内置默认的邮件通知,但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容.无法定义发送邮件的格式 ...