生产者消费者模式是并发、多线程编程中经典的

真实世界中的生产者消费者模式

生产者和消费者模式在生活当中随处可见,它描述的是协调与协作的关系。比如一个人正在准备食物(生产者),而另一个人正在吃(消费者),他们使用一个共用的桌子用于放置盘子和取走盘子,生产者准备食物,如果桌子上已经满了就等待,消费者(那个吃的)等待如果桌子空了的话。这里桌子就是一个共享的对象。在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.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

import java.util.logging.Level;

import java.util.logging.Logger;

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 sharedQueue;

public Producer(BlockingQueue sharedQueue) {

this.sharedQueue = sharedQueue;

}

@Override

public void run() {

for(int i=0; i<10; i++){

try {

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 sharedQueue;

public Consumer (BlockingQueue sharedQueue) {

this.sharedQueue = sharedQueue;

}

@Override

public void run() {

while(true){

try {

System.out.println("Consumed: "+ sharedQueue.take());

} catch (InterruptedException ex) {

Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

}

Output:

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

来源:http://www.importnew.com/6695.html

java consumed_Java设计模式—生产者消费者模式(阻塞队列实现)相关推荐

  1. 生产者/消费者模式(阻塞队列)

    生产消费者模式  貌似也是阻塞的问题  花了一些时间终于弄明白这个鸟东东,以前还以为是不复杂的一个东西的,以前一直以为和观察者模式差不多(其实也是差不多的,呵呵),生产消费者模式应该是可以通过观察者模 ...

  2. Java线程实现生产者—消费者模式

    在这里插入代码片# Java 线程实现生产者-消费者模式 ##思路:实现类似消费者生产者线程之间通讯的功能,每创建一个工人,就让这个工人干活,干一段时间,工人自动消失,然后又去创建一个工人干活: 代码 ...

  3. java 消费者模式 多线程_[Java并发-24-并发设计模式] 生产者-消费者模式,并发提高效率...

    生产者 - 消费者模式在编程领域的应用非常广泛,前面我们曾经提到,Java 线程池本质上就是用生产者 - 消费者模式实现的,所以每当使用线程池的时候,其实就是在应用生产者 - 消费者模式. 当然,除了 ...

  4. 设计模式——生产者消费者模式

    1 基本概括 2 主要介绍 2.1 概念 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消 ...

  5. 【java并发系列】java多线程实现生产者消费者模式

    大家好,我是walker 一个从文科自学转行的程序员~ 爱好编程,偶尔写写编程文章和生活 欢迎关注公众号[I am Walker],回复"电子书",就可以获得200多本编程相关电子 ...

  6. 设计模式—生产者消费者模式

    生产者消费者模式是指生产者和消费者通过一个缓冲区(通常是一个队列)的进行通讯.生产者生产完数据之后不用等待消费者处理,直接放到缓冲区,消费者不找生产者要数据,而是直接从缓冲区里取,这样既能够保持生产者 ...

  7. Java线程实现生产者消费者模式

    1 什么是生产者消费者模式 想一个现实生活中的例子,啤酒商---超市---消费者也就是我们,啤酒商生产了啤酒,然后将啤酒销售给了超市,我们消费之又会到超市将啤酒买回来自己喝,那么啤酒商和消费者之间是什 ...

  8. Java 并发(生产者/消费者 模式)

    >生产者/消费者 模式角色:生产者,消费者都是线程,两者中间是容器,容器内部是产品. 要求: 容器 里面要定义容量 容器 往里面添加(满时等待) 或者 从里面删除(空时等待) ,都要是阻塞的(等 ...

  9. 设计模式-生产者消费者模式

    常见场景: 某个模块负责产生数据,这些数据由另一个模块来负责处理.产生数据的模块,就形象地称为生产者:而处理数据的模块,就称为消费者. 该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介.生 ...

最新文章

  1. 【c语言】判断一个数是否为素数
  2. Asp.net中防止用户多次登录的方法
  3. sql 外连接的写法。
  4. 【学术研讨课】雷诺实验2018-06-13
  5. Swift版音乐播放器(简化版),swift音乐播放器
  6. android和ios HybridApp的js交互
  7. Fiddler (二) : Script 的 用法
  8. 实现tomcat的https单向认证及双向认证
  9. 大班线描机器人_大班美术教案机器人
  10. php遍历原理,PHP数组遍历与实现原理
  11. 了解SQL Server事务日志备份和完整备份的日志序列号
  12. 静态路由实现路由过滤
  13. IDEA的Mybatis插件
  14. gridview的sort_C#教程之Gridview自动排序功能的实现
  15. 计算机如何识别英语,Excel自动识别中英文妙招三则 -电脑资料
  16. python 二项分布_如何理解python中的二项分布?
  17. NEFU 262 贪吃的九头龙(树形背包,4级)
  18. 美国国土安全部承认使用数据库追踪数百万手机用户
  19. go发送smtp邮件时的踩坑记录——auth login、x509: cannot validate certificate for错误
  20. python excel画图哪个好_Python excel 画图

热门文章

  1. return、reutrn false、e.preventDefault、e.stopPropagation、e.stopImmediatePropagation的区别
  2. 关于 Vue.js:那些好的,不怎么样的和糟糕的
  3. Ceph FINDING AN OBJECT LOCATION
  4. adb概览及协议參考
  5. RHEL6入门系列之三,GNU计划与Linux发行版
  6. linux monit安装配置
  7. OpenCV-图像像素遍历操作的三种方法对比(程序提速)
  8. android activty动画,Activity动画效果
  9. mysql新增加密字段_mysql字段加密
  10. 前端 鼠标一次移动半个像素_今天来说说鼠标的DPI该怎么设置