阻塞队列实现生产者消费者模式
来源:互联网 发布:给网络销售平台供货 编辑:程序博客网 时间:2024/04/30 01:14
生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。这篇文章我们来看看什么是生产者消费者模式,这个问题也是多线程面试题中经常被提及的。如何使用阻塞队列(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代码,它更易于理解。
importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.LinkedBlockingQueue;importjava.util.logging.Level;importjava.util.logging.Logger; publicclass ProducerConsumerPattern { publicstatic void main(String args[]){ //Creating shared object BlockingQueue sharedQueue = newLinkedBlockingQueue(); //Creating Producer and Consumer Thread Thread prodThread = newThread(newProducer(sharedQueue)); Thread consThread = newThread(newConsumer(sharedQueue)); //Starting producer and Consumer thread prodThread.start(); consThread.start(); } } //Producer Class in javaclassProducer implementsRunnable { privatefinal BlockingQueue sharedQueue; publicProducer(BlockingQueue sharedQueue) { this.sharedQueue = sharedQueue; } @Override publicvoid run() { for(inti=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 JavaclassConsumer implementsRunnable{ privatefinal BlockingQueue sharedQueue; publicConsumer (BlockingQueue sharedQueue) { this.sharedQueue = sharedQueue; } @Override publicvoid 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:0Produced:1Consumed:0Produced:2Consumed:1Produced:3Consumed:2Produced:4Consumed:3Produced:5Consumed:4Produced:6Consumed:5Produced:7Consumed:6Produced:8Consumed:7Produced:9Consumed:8Consumed:9
你可以看到生产者线程生产数和消费者线程消费它以FIFO的顺序,因为阻塞队列只允许元素以FIFO的方式来访问。以上就是使用阻塞队列解决生产者消费者问题的全部,我确信它比wait/notify更简单,但你要两者都准备如果你是去面试话。
原文链接: Javarevisited
译文链接: http://www.importnew.com/6695.html
- 阻塞队列实现生产者消费者模式
- 阻塞队列---实现生产者消费者模式
- 阻塞队列实现生产者消费者模式
- 阻塞队列实现生产者消费者模式
- 阻塞队列实现生产者消费者模式
- 阻塞队列实现生产者消费者模式
- 生产者-消费者模式(阻塞队列实现)
- 阻塞队列实现生产者消费者模式
- 阻塞队列实现的生产者/消费者模式
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 生产者/消费者模式(阻塞队列)
- 阻塞队列实现生产者消费者
- CentOS安装php mbstring的扩展
- hibernate操作视图的问题
- Android的选项菜单,用代码编写
- Audio系统和上层接口
- 手机归属地查询示例
- 阻塞队列实现生产者消费者模式
- 笔记19 日期类
- cfg80211的kernel架构(基于Linux 3.08)之sta
- 学习方法-在解决问题中学习
- 杭电ACM 2022
- boost静态断言的简单实现
- windows批处理实现telnet登陆和运行命令--还有问题
- 安卓实例
- 最简单方法三步实现linux系统开机oralce自动启动