Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 371|回复: 0

[默认分类] Java设计模式—生产者消费者模式(阻塞队列实现)

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-10 13:39:18 | 显示全部楼层 |阅读模式


      



      
       
      
      
       生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。这篇文章我们来看看什么是生产者消费者模式,这个问题也是多线程面试题中经常被提及的。如何使用阻塞队列(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.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
         
       
       
      
      
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-3-28 16:59 , Processed in 0.365450 second(s), 50 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表