java生产者消费者模式式队列和数组的区别

java多线程消费者生产者模式(BlockingQueue 通过阻塞队列实现) -
- ITeye博客
博客分类:
import java.util.concurrent.BlockingQ
import java.util.concurrent.LinkedBlockingQ
* Created with IntelliJ IDEA.
* User: csx
* Date: 4/24/14
* Time: 9:56 AM
* To change this template use File | Settings | File Templates.
* 生产者与消费者模型中,要保证以下几点:
* 1 同一时间内只能有一个生产者生产
* 2 同一时间内只能有一个消费者消费
* 3 生产者生产的同时消费者不能消费
* 4 消费者消费的同时生产者不能生产
* 5 共享空间空时消费者不能继续消费
* 6 共享空间满时生产者不能继续生产
* 使用并发库中的BlockingQueue(阻塞队列) 实现生产者与消费者
public class WaitNoticeDemo {
public static void main(String[] args) {
//固定容器大小为10
BlockingQueue&Food& foods = new LinkedBlockingQueue&Food&(10);
Thread produce = new Thread(new Produce(foods));
Thread consume = new Thread(new Consume(foods));
produce.start();
consume.start();
class Produce implements Runnable{
private BlockingQueue&Food&
Produce(BlockingQueue&Food& foods) {
this.foods =
public void run() {
int i = 0;
while (true){
//当生产的食品数量装满了容器,那么在while里面该食品容器(阻塞队列)会自动阻塞
wait状态 等待消费
foods.put(new Food("食品"+i));
} catch (InterruptedException e) {
e.printStackTrace();
//To change body of catch statement use File | Settings | File Templates.
class Consume implements Runnable {
private BlockingQueue&Food&
Consume(BlockingQueue&Food& foods){
this.foods =
public void run() {
Thread.sleep(1000);
//用于测试当生产者生产满10个食品后是否进入等待状态
while (true){
//当容器里面的食品数量为空时,那么在while里面该食品容器(阻塞队列)会自动阻塞
wait状态 等待生产
Food food = foods.take();
System.out.println("消费"+food.getName());
} catch (InterruptedException e) {
e.printStackTrace();
//To change body of catch statement use File | Settings | File Templates.
class Food{
String getName() {
Food(String name){
this.name =
System.out.println("生产"+name);
如有不足 还请大家留言纠正修改。
lucky_xingxing
浏览: 60693 次
来自: 成都
我是3.1的版本 怎么还是报这个错
谢谢!!也解决了我的问题。
也解决了我的问题,谢谢!
Arrays.sort(keys);性能差。。。
你有强迫症哦 ...
这种在通过like查找的时候,和list是一样的。HashMa ...LabVIEW之生产者/消费者模式--队列操作
来源:博客园
LabVIEW之生产者/消费者模式--队列操作
彭会锋 
本文章主要是对学习LabVIEW之生产者/消费者模式的学习笔记,其中涉及到同步控制技术-队列、事件、状态机、生产者-消费者模式,这几种技术在在本章中都会有侧重点的进行介绍和总结!
队列同步技术-操作函数
同步控制技术可以实现在多个VI之间或者同一VI 不同县城之间同步任务和交换数据;在LabVIEW中提供了‘同步’函数选板,包括通知器、队列、信号量、集合点、事件、首次调用函数,本文主要关注同步控制技术之队列技术:
队列操作函数:
1 “获取队列引用”函数

 2 "元素入队列" 和 “元素出队列” 函数


函数作用:将元素入队列和出队列用(没什么好说的!)
超时毫秒(-1)端子:如果未连接,默认输入值为-1,表示永不超时,如果队列满,则一直等待直到队列有空位为止;
如果连接端子,则新元素等待设定时间后仍无法入队列,则结束本次等待!

 3 “最前端插入元素” 和 “有损耗元素入队列” 函数


函数作用:将元素插入队列,不过插入队列方式有区别;
元素入队列、最前端插入元素、有损耗元素入队列三者区别:”元素入队列“函数采用先入后出次序,而“最前端插入元素”函数则采用后入先出(FIFO)的原则,类似于堆栈,因此可以使用队列实现堆栈效果,相比数组实现有优势;“元素入队列”函数如果队列满,则线程等待,直到有空位为止;“有损耗元素入队列”在这种情况下则会自动删除队列前端元素,并在末端插入元素,可以用于实现缓冲区效果;

4 “预览队列元素”函数


预览队列元素和元素出队列区别:当返回队列前段的元素时,是否删除该元素!

5 “获取队列状态”函数:主要用于判定队列引用是否有效!

6 “清空队列”和“释放队列引用”函数


“清空队列”函数:清楚队列所有元素,并以数组形式返回元素,用于一次全部读取队列元素;

队列课后练习
1 基于队列的数据采集系统


在此程序设计中学习到的知识:
1 数据类型和采用显示控件的关系:此队列的数据类型为一维数组,所以在元素出队列时的元素也为一维数组,因此要采用波形图空间;
2 子程序VI中设置了“等待函数”,但是没有while循环,将子VI放入while循环中,相当于在while循环中添加了“等待函数”,其实对其的理解可以从c语言中加深理解;3 while循环中停止条件的处理:对于入队列循环,停止只意味着本循环停止,但并不意味着整个程序停止运行了,因为还有两个循环在运行;对于元素出队列循环,当元素空的时候会发生超时错误,进而停止本循环;在元素出队列循环停止后会销毁队列引用,从而导致获取队列状态循环出错,进而停止循环。具体结果如下:

 2 队列传递数据练习


此程序学到的知识:
1 队列数据类型设置为常量,所以用于数据显示的控件为波形图控件;2 注释的箭头设置:函数-&编程-&结构-&修饰


 3 多数据源输入队列程序

此程序学习知识点:
1 对于队列的创建:通过队列创建函数的名字搜索该引用,如果没有则创建,如果有,则直接加入队列2 此程序采用三个while循环创建三个线程,并将数据同时加入一个队列中,并最终进行显示3 注意此程序中对while循环的停止条件的处理;

免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动阻塞队列实现生产者消费者模式 - ImportNew
生产者消费者模式是并发、多线程编程中经典的,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。这篇文章我们来看看什么是生产者消费者模式,这个问题也是多线程面试题中经常被提及的。如何使用阻塞队列(Blocking Queue)解决生产者消费者模式,以及使用生产者消费者模式的好处。
真实世界中的生产者消费者模式
生产者和消费者模式在生活当中随处可见,它描述的是协调与协作的关系。比如一个人正在准备食物(生产者),而另一个人正在吃(消费者),他们使用一个共用的桌子用于放置盘子和取走盘子,生产者准备食物,如果桌子上已经满了就等待,消费者(那个吃的)等待如果桌子空了的话。这里桌子就是一个共享的对象。在Java Executor框架自身实现了生产者消费者模式它们分别负责添加和执行任务。
生产者消费者模式的好处
它的确是一种实用的设计模式,常用于编写多线程或并发代码。下面是它的一些优点:
它简化的开发,你可以独立地或并发的编写消费者和生产者,它仅仅只需知道共享对象是谁
生产者不需要知道谁是消费者或者有多少消费者,对消费者来说也是一样
生产者和消费者可以以不同的速度执行
分离的消费者和生产者在功能上能写出更简洁、可读、易维护的代码
多线程中的生产者消费者问题
生产者消费者问题是一个流行的面试题,面试官会要求你实现生产者消费者设计模式,以至于能让生产者应等待如果队列或篮子满了的话,消费者等待如果队列或者篮子是空的。这个问题可以用不同的方式来现实,经典的方法是使用wait和notify方法在生产者和消费者线程中合作,在队列满了或者队列是空的条件下阻塞,Java5的阻塞队列(BlockingQueue)数据结构更简单,因为它隐含的提供了这些控制,现在你不需要使用wait和nofity在生产者和消费者之间通信了,阻塞队列的put()方法将阻塞如果队列满了,队列take()方法将阻塞如果队列是空的。在下部分我们可以看到代码例子。
使用阻塞队列实现生产者消费者模式
阻塞队列实现生产者消费者模式超级简单,它提供开箱即用支持阻塞的方法put()和take(),开发者不需要写困惑的wait-nofity代码去实现通信。BlockingQueue 一个接口,Java5提供了不同的现实,如ArrayBlockingQueue和LinkedBlockingQueue,两者都是先进先出(FIFO)顺序。而ArrayLinkedQueue是自然有界的,LinkedBlockingQueue可选的边界。下面这是一个完整的生产者消费者代码例子,对比传统的wait、nofity代码,它更易于理解。
import java.util.concurrent.BlockingQ
import java.util.concurrent.LinkedBlockingQ
import java.util.logging.L
import java.util.logging.L
public class ProducerConsumerPattern {
public static void main(String args[]){
//Creating shared object
BlockingQueue sharedQueue = new LinkedBlockingQueue();
//Creating Producer and Consumer Thread
Thread prodThread = new Thread(new Producer(sharedQueue));
Thread consThread = new Thread(new Consumer(sharedQueue));
//Starting producer and Consumer thread
prodThread.start();
consThread.start();
//Producer Class in java
class Producer implements Runnable {
private final BlockingQueue sharedQ
public Producer(BlockingQueue sharedQueue) {
this.sharedQueue = sharedQ
public void run() {
for(int i=0; i&10; i++){
System.out.println(&Produced: & + i);
sharedQueue.put(i);
} catch (InterruptedException ex) {
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
//Consumer Class in Java
class Consumer implements Runnable{
private final BlockingQueue sharedQ
public Consumer (BlockingQueue sharedQueue) {
this.sharedQueue = sharedQ
public void run() {
while(true){
System.out.println(&Consumed: &+ sharedQueue.take());
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
Produced: 0
Produced: 1
Consumed: 0
Produced: 2
Consumed: 1
Produced: 3
Consumed: 2
Produced: 4
Consumed: 3
Produced: 5
Consumed: 4
Produced: 6
Consumed: 5
Produced: 7
Consumed: 6
Produced: 8
Consumed: 7
Produced: 9
Consumed: 8
Consumed: 9
你可以看到生产者线程生产数和消费者线程消费它以FIFO的顺序,因为阻塞队列只允许元素以FIFO的方式来访问。以上就是使用阻塞队列解决生产者消费者问题的全部,我确信它比wait/notify更简单,但你要两者都准备如果你是去面试话。
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
程序员,关注 Java、Python、云计算,移动互联网。(新浪微博:)
我遇见了一个问题 ,这个问题是我并没有使用
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2017 ImportNewJava 通过阻塞队列实现生产者消费者模式 - 简书
Java 通过阻塞队列实现生产者消费者模式
阻塞队列 Blocking Queue
当队列空时,获取元素的线程会等待
当队列满时,存储元素的线程会等待
提供的方法:
插入元素:
add(e):抛出异常
offer(e):返回特殊值
put(e):一直阻塞
offer(e,time,unit):超时退出
移除元素:
remove():抛出异常
poll():返回特殊值
take():一直阻塞
poll(time,unit):超时退出
JDK 7 提供了 7 个阻塞队列
ArrayBlockingQueue :一个由数组结构组成的 有界 阻塞队列。
此队列按照先进先出(FIFO)的原则对元素进行排序。
默认情况下不保证访问者公平的访问队列,所谓公平访问队列是指阻塞的所有生产者线程或消费者线程,当队列可用时,可以按照阻塞的先后顺序访问队列,即先阻塞的生产者线程,可以先往队列里插入元素,先阻塞的消费者线程,可以先从队列里获取元素。通常情况下为了保证公平性会降低吞吐量。我们可以使用以下代码创建一个公平的阻塞队列:ArrayBlockingQueue fairQueue = new
ArrayBlockingQueue(1000,true);
LinkedBlockingQueue :一个由链表结构组成的 有界 阻塞队列。
此队列按照先进先出(FIFO)的原则对元素进行排序。
PriorityBlockingQueue :一个支持优先级排序的 无界 阻塞队列。
默认情况下元素采取自然顺序排列,也可以通过比较器 comparator 来指定元素的排序规则。元素按照升序排列。
DelayQueue:一个使用优先级队列实现的无界阻塞队列。
SynchronousQueue:一个不存储元素的阻塞队列。
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
关于 通过 wait 和 notify 实现生产者消费者模式,可以参考 。关于 通过 Lock 和 竞争条件 Condition 实现生产者消费者模式,可以参考 。
利用阻塞队列实现生产者消费者模式,代码如下:
public class BlockingQueue_Test {
private static final int MAX_CAPACITY = 10;
private static ArrayBlockingQueue&Object& goods = new ArrayBlockingQueue&Object&(MAX_CAPACITY);
public static void main(String[] args) {
(new ProducerThread()).start();
(new ConsumerThread()).start();
static class ProducerThread extends Thread {
public void run() {
while (true) {
// 每隔 1000 毫秒生产一个商品
Thread.sleep(1000);
goods.put(new Object());
System.out.println("Produce goods, total: " + goods.size());
} catch (InterruptedException e) {
static class ConsumerThread extends Thread {
public void run() {
while (true) {
// 每隔 500 毫秒消费一个商品
Thread.sleep(500);
goods.take();
System.out.println("Consume goods, total: " + goods.size());
} catch (InterruptedException e) {
阻塞队列的实现原理
以 ArrayBlockingQueue 为例,实际上使用了 ReentrantLock 和 Condition。
构造方法:
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity &= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
lock.newCondition();
插入元素,如果队列已满,则阻塞 notFull.await();:
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.
lock.lockInterruptibly();
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
移除元素,如果队列已空,则阻塞 notEmpty.await();:
public E take() throws InterruptedException {
final ReentrantLock lock = this.
lock.lockInterruptibly();
while (count == 0)
notEmpty.await();
return dequeue();
} finally {
lock.unlock();
生命不息,折腾不止。
兼职推荐工作,上海的同志请联系 。

我要回帖

更多关于 生产者消费者消息队列 的文章

 

随机推荐