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

本文由 TonySpark 翻译自 Javarevisited转载请参见文章末尾的要求。

Java.util.concurrent.BlockingQueue 是一个队列实现类,支持这样的操作:当从队列中获取或者移除元素时,如果队列为空,需要等待,直到队列不为空;同时如果向队列中添加元素时,此时如果队列无可用空间,也需要等待。

BlockingQueue 类不接收Null值,如果你试图向队列中存入Null值将抛出NullPointerException.

BlockingQueue的实现是线程安全的。所有队列方法本身都是原子操作,使用并发控制的内部锁或者其它形式。

BlockingQueue这个接口是Java集合架构的一部分,它主要用于解决生产者/消费者问题。在BlockingQueue中,我们不用担心生产者操作时是否有可用空间或者消费者操作时是否有可用的对像而等待这样的问题,这些都会在它的实现类中进行处理。

Java中提供了几个对BlockingQueue的实现类,如: ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue 等

在处理生产者/消费者问题上 我们将会使用ArrayBlockingQueue来实现,如下是我们需知道的重要方法:

  • put(E e): 这个方法用于向队列中插入元素,如果队列已满,需要等待可用的这间。
  • E take(): 这个方法用于从队列头部获取或者移除元素,如果队列为空则需要等待可用的元素。

现在咱们看看用BlockingQueue来解决生产者/消费者问题。

Message

Producer产生的普通Java对象,并添加到队列中。

Message.java

 package com.journaldev.concurrency;

 public class Message {
private String msg; public Message(String str){
this.msg=str;
} public String getMsg() {
return msg;
} }

Producer

Producer这个类会产生消息并将其放入队列中。

Producer.java

package com.journaldev.concurrency;

import java.util.concurrent.BlockingQueue;

public class Producer implements Runnable {

    private BlockingQueue<Message> queue;

    public Producer(BlockingQueue<Message> q){
this.queue=q;
}
@Override
public void run() {
//生产消息
for(int i=0; i<100; i++){
Message msg = new Message(""+i);
try {
Thread.sleep(i);
queue.put(msg);
System.out.println("Produced "+msg.getMsg());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//添加退出消息
Message msg = new Message("exit");
try {
queue.put(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

Consumer

Consumer类会从队列获取消息进行处理。如果获取的是退出消息则结束。

Consumer.java

package com.journaldev.concurrency;

import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable{

private BlockingQueue<Message> queue;

    public Consumer(BlockingQueue<Message> q){
this.queue=q;
} @Override
public void run() {
try{
Message msg;
//获取并处理消息直到接收到“exit”消息
while((msg = queue.take()).getMsg() !="exit"){
Thread.sleep(10);
System.out.println("Consumed "+msg.getMsg());
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}

ProducerConsumerService

生产者/消费者的服务类将会产生固定大小的BlockingQueue,生产者和消费者同时共享该BlockingQueue,该服务类会起启动生产者和消费者线程。

ProducerConsumerService.java

 package com.journaldev.concurrency;

 import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; public class ProducerConsumerService { public static void main(String[] args) {
//创建大小为10的 BlockingQueue
BlockingQueue<Message> queue = new ArrayBlockingQueue<>(10);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
//开启 producer线程向队列中生产消息
new Thread(producer).start();
//开启 consumer线程 中队列中消费消息
new Thread(consumer).start();
System.out.println("Producer and Consumer has been started");
} }

上面程序的运行结果:

 Producer and Consumer has been started
Produced 0
Produced 1
Produced 2
Produced 3
Produced 4
Consumed 0
Produced 5
Consumed 1
Produced 6
Produced 7
Consumed 2
Produced 8
...

Thread sleep 使得生产者/消费者 生产、消费这此消息有一定的延迟。

原文链接: Javarevisited 翻译: TonySpark
译文链接: http://www.cnblogs.com/tonyspark/p/3722013.html

转载请保留原文出处、译者和译文链接。]

Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例的更多相关文章

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

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

  2. 用阻塞队列实现一个生产者消费者模型?synchronized和lock有什么区别?

    多线程当中的阻塞队列 主要实现类有 ArrayBlockingQueue是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 LinkedBlockingQueue是一个基于链表结构的 ...

  3. JUC 并发编程--07 阻塞队列版本的 生产者消费者(不使用synchronized和 lock),也有一些疑惑,最终解惑

    直接上代码: 前提是你已经 熟悉了原子类,volatile,和阻塞队列 public class JucPCdemo03 { /** * 阻塞队列的应用: 这里实现的生产者消费者,生产一个消费一个 * ...

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

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

  5. 细说并发4:Java 阻塞队列源码分析(上)

    上篇文章 趣谈并发3:线程池的使用与执行流程 中我们了解到,线程池中需要使用阻塞队列来保存待执行的任务.这篇文章我们来详细了解下 Java 中的阻塞队列究竟是什么. 读完你将了解: 什么是阻塞队列 七 ...

  6. 使用Java的BlockingQueue实现生产者-消费者

    http://tonl.iteye.com/blog/1936391 使用Java的BlockingQueue实现生产者-消费者 博客分类: Java JavaBlockingQueue阻塞队列  B ...

  7. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

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

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

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

  9. Java并发包源码学习系列:阻塞队列BlockingQueue及实现原理分析

    目录 本篇要点 什么是阻塞队列 阻塞队列提供的方法 阻塞队列的七种实现 TransferQueue和BlockingQueue的区别 1.ArrayBlockingQueue 2.LinkedBloc ...

随机推荐

  1. WordPress博客搭建指南

    WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统.WordPress具有插件架构和模板系统.Alexa排行前100万的网站中有超过16.7%的网站使用WordPre ...

  2. redis win连接以及配置连接密码

    redis连接格式为 redis-cli -h host -p port -a password 但由于刚安装的redis是没有密码的 因此可以进行直接连接, cd转到redis目录里 redis-c ...

  3. Unity3d导入3dmax后model 的缩放为0.0254的原因以及解决办法

    http://blog.csdn.net/pdw_jsp/article/details/51259493 这个问题其实已经早都出现过了,今天我们这边也碰到了,这里做个记录吧 导致的问题~ 场景的比例 ...

  4. PHP SOAP 提交XML

    <?php $xmldata = <<<EOT <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap. ...

  5. Codevs 1159 最大全0子矩阵

    1159 最大全0子矩阵  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 在一个0,1方阵中找出其中最大的全 ...

  6. 洛谷P1074 靶形数独(跳舞链)

    传送门 坑着,等联赛之后再填(联赛挂了就不填了233) //minamoto #include<iostream> #include<cstdio> #include<c ...

  7. php网页上一页下一页翻页

    这几天做项目因为数据太多,需要对信息进行上下翻页展示,就自己写了翻页的代码 大致功能就是页面只显示几条信息,按上一页.下一页切换内容,当显示第一页时上一页和首页选项不可选,当页面加载到最后一页时下一页 ...

  8. SpringMVC之WebMVC介绍

    一.MVC是什么 二.常用的MVC框架 三.MVC模式的优缺点 四.SpringMVC简介

  9. JS高级学习历程-3

    JS-作用域链及作用 [作用域链] 1 什么事作用域链 一个变量,在当前环境可以使用,当前环境的内部环境也可以使用,内部的深层环境...也可以使用,变量在不同环境都可以使用的现象想成了一个链条,称为“ ...

  10. shell编程 条件判断式----利用 if .... then ----多重

    条件判断式----利用 if .... then ----多重 在同一个数据的判断中,如果该数据需要进行多种不同的判断时,应该怎么作?举例来说,上面的 sh06.sh 脚本中,我们只要进行一次 $yn ...