生产者-消费者模式的实现方式

8人阅读 评论(0) 收藏 举报


1、背景                                                                    

生产者生产数据到缓冲区中,消费者从缓冲区中取数据。

如果缓冲区已经满了,则生产者线程阻塞;

如果缓冲区为空,那么消费者线程阻塞

复制代码


方式一:synchronized、wait和notify                


  1 package producerConsumer;
  2 //wait 和 notify
  3 public class ProducerConsumerWithWaitNofity {
  4     public static void main(String[] args) {
  5         Resource resource = new Resource();
  6         //生产者线程
  7         ProducerThread p1 = new ProducerThread(resource);
  8         ProducerThread p2 = new ProducerThread(resource);
  9         ProducerThread p3 = new ProducerThread(resource);
 10         //消费者线程
 11         ConsumerThread c1 = new ConsumerThread(resource);
 12         //ConsumerThread c2 = new ConsumerThread(resource);
 13         //ConsumerThread c3 = new ConsumerThread(resource);
 14     
 15         p1.start();
 16         p2.start();
 17         p3.start();
 18         c1.start();
 19         //c2.start();
 20         //c3.start();
 21     }
 22     
 23     
 24     
 25 }
 26 /**
 27  * 公共资源类
 28  * @author 
 29  *
 30  */
 31 class Resource{//重要
 32     //当前资源数量
 33     private int num = 0;
 34     //资源池中允许存放的资源数目
 35     private int size = 10;
 36 
 37     /**
 38      * 从资源池中取走资源
 39      */
 40     public synchronized void remove(){
 41         if(num > 0){
 42             num--;
 43             System.out.println("消费者" + Thread.currentThread().getName() +
 44                     "消耗一件资源," + "当前线程池有" + num + "个");
 45             notifyAll();//通知生产者生产资源
 46         }else{
 47             try {
 48                 //如果没有资源,则消费者进入等待状态
 49                 wait();
 50                 System.out.println("消费者" + Thread.currentThread().getName() + "线程进入等待状态");
 51             } catch (InterruptedException e) {
 52                 e.printStackTrace();
 53             }
 54         }
 55     }
 56     /**
 57      * 向资源池中添加资源
 58      */
 59     public synchronized void add(){
 60         if(num < size){
 61             num++;
 62             System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有" 
 63             + num + "个");
 64             //通知等待的消费者
 65             notifyAll();
 66         }else{
 67             //如果当前资源池中有10件资源
 68             try{
 69                 wait();//生产者进入等待状态,并释放锁
 70                 System.out.println(Thread.currentThread().getName()+"线程进入等待");
 71             }catch(InterruptedException e){
 72                 e.printStackTrace();
 73             }
 74         }
 75     }
 76 }
 77 /**
 78  * 消费者线程
 79  */
 80 class ConsumerThread extends Thread{
 81     private Resource resource;
 82     public ConsumerThread(Resource resource){
 83         this.resource = resource;
 84     }
 85     @Override
 86     public void run() {
 87         while(true){
 88             try {
 89                 Thread.sleep(1000);
 90             } catch (InterruptedException e) {
 91                 e.printStackTrace();
 92             }
 93             resource.remove();
 94         }
 95     }
 96 }
 97 /**
 98  * 生产者线程
 99  */
100 class ProducerThread extends Thread{
101     private Resource resource;
102     public ProducerThread(Resource resource){
103         this.resource = resource;
104     }
105     @Override
106     public void run() {
107         //不断地生产资源
108         while(true){
109             try {
110                 Thread.sleep(1000);
111             } catch (InterruptedException e) {
112                 e.printStackTrace();
113             }
114             resource.add();
115         }
116     }
117     
118 }
复制代码

方式二:lock和condition的await、signalAll

复制代码
  1 package producerConsumer;
  2 
  3 import java.util.concurrent.locks.Condition;
  4 import java.util.concurrent.locks.Lock;
  5 import java.util.concurrent.locks.ReentrantLock;
  6 /**
  7  * 使用Lock 和 Condition解决生产者消费者问题
  8  * @author tangzhijing
  9  *
 10  */
 11 public class LockCondition {
 12         public static void main(String[] args) {
 13             Lock lock = new ReentrantLock();
 14             Condition producerCondition = lock.newCondition();
 15             Condition consumerCondition = lock.newCondition();
 16             Resource2 resource = new Resource2(lock,producerCondition,consumerCondition);
 17             
 18             //生产者线程
 19             ProducerThread2 producer1 = new ProducerThread2(resource);
 20             
 21             //消费者线程
 22             ConsumerThread2 consumer1 = new ConsumerThread2(resource);
 23             ConsumerThread2 consumer2 = new ConsumerThread2(resource);
 24             ConsumerThread2 consumer3 = new ConsumerThread2(resource);
 25             
 26             producer1.start();
 27             consumer1.start();
 28             consumer2.start();
 29             consumer3.start();
 30         }
 31 }
 32 /**
 33  * 消费者线程
 34  */
 35 class ConsumerThread2 extends Thread{
 36     private Resource2 resource;
 37     public ConsumerThread2(Resource2 resource){
 38         this.resource = resource;
 39         //setName("消费者");
 40     }
 41     public void run(){
 42         while(true){
 43             try {
 44                 Thread.sleep((long) (1000 * Math.random()));
 45             } catch (InterruptedException e) {
 46                 e.printStackTrace();
 47             }
 48             resource.remove();
 49         }
 50     }
 51 }
 52 /**
 53  * 生产者线程
 54  * @author tangzhijing
 55  *
 56  */
 57 class ProducerThread2 extends Thread{
 58     private Resource2 resource;
 59     public ProducerThread2(Resource2 resource){
 60         this.resource = resource;
 61         setName("生产者");
 62     }
 63     public void run(){
 64         while(true){
 65                 try {
 66                     Thread.sleep((long) (1000 * Math.random()));
 67                 } catch (InterruptedException e) {
 68                     e.printStackTrace();
 69                 }
 70                 resource.add();
 71         }
 72     }
 73 }
 74 /**
 75  * 公共资源类
 76  * @author tangzhijing
 77  *
 78  */
 79 class Resource2{
 80     private int num = 0;//当前资源数量
 81     private int size = 10;//资源池中允许存放的资源数目
 82     private Lock lock;
 83     private Condition producerCondition;
 84     private Condition consumerCondition;
 85     public Resource2(Lock lock, Condition producerCondition, Condition consumerCondition) {
 86         this.lock = lock;
 87         this.producerCondition = producerCondition;
 88         this.consumerCondition = consumerCondition;
 89  
 90     }
 91     /**
 92      * 向资源池中添加资源
 93      */
 94     public void add(){
 95         lock.lock();
 96         try{
 97             if(num < size){
 98                 num++;
 99                 System.out.println(Thread.currentThread().getName() + 
100                         "生产一件资源,当前资源池有" + num + "个");
101                 //唤醒等待的消费者
102                 consumerCondition.signalAll();
103             }else{
104                 //让生产者线程等待
105                 try {
106                     producerCondition.await();
107                     System.out.println(Thread.currentThread().getName() + "线程进入等待");
108                 } catch (InterruptedException e) {
109                     e.printStackTrace();
110                 }
111             }
112         }finally{
113             lock.unlock();
114         }
115     }
116     /**
117      * 从资源池中取走资源
118      */
119     public void remove(){
120         lock.lock();
121         try{
122             if(num > 0){
123                 num--;
124                 System.out.println("消费者" + Thread.currentThread().getName() 
125                         + "消耗一件资源," + "当前资源池有" + num + "个");
126                 producerCondition.signalAll();//唤醒等待的生产者
127             }else{
128                 try {
129                     consumerCondition.await();
130                     System.out.println(Thread.currentThread().getName() + "线程进入等待");
131                 } catch (InterruptedException e) {
132                     e.printStackTrace();
133                 }//让消费者等待
134             }
135         }finally{
136             lock.unlock();
137         }
138     }
139     
140 }
复制代码


查看评论

设计模式之建造者模式详解与应用

-
  • 1970年01月01日 08:00

生产者消费者模式的几种实现方式以及线程安全问题

生产者消费者模式的几种实现方式拿我们生活中的例子来说,工厂生产出来的产品总是要输出到外面使用的,这就是生产与消费的概念。 在我们实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数...
  • noaman_wgs
  • noaman_wgs
  • 2017-03-27 11:40:29
  • 2346

JAVA多线程(三)生产者消费者模式及实现方法

介绍了生产者消费者模式以及实现方法(wait&notify,阻塞队列
  • antony9118
  • antony9118
  • 2016-05-23 15:15:02
  • 5062

如何实现生产者消费者模式

生产/消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”、“消费者”、“仓库”和“产品”。他们之间的关系如下: ① 生产者仅仅在仓储未满时候生产,仓满则停止生产。 ② 消费者仅仅在仓储...
  • u010339647
  • u010339647
  • 2016-07-24 11:33:45
  • 5456

生产者和消费者三种实现

1、syncronized+wait+notifypackage com.rrfare.producerconsumer;import java.util.LinkedList; import jav...
  • liupeng_qwert
  • liupeng_qwert
  • 2017-07-11 22:22:59
  • 277

消费者模式的三种实现方式

1、使用 2、使用jdk
  • HEYUTAO007
  • HEYUTAO007
  • 2014-08-20 22:16:34
  • 1560

多任务并发之生产者消费者模式应用

生产者-消费者模式大家都很熟悉,生产者负责生产数据,并存放到队列中,消费者负责从队列中取出数据来消费。可以看出生产者和消费者之间不直接通讯,是通过队列来通讯的。 生产者和消费者是抽象的概念,可以是线程...
  • guozebo
  • guozebo
  • 2016-05-28 22:58:41
  • 3701

生产者消费者的五种实现方式

大牛博主写的一篇文章,感觉以后会用的上,所以先收藏哈hhh... 原链接:http://blog.zgj12138.cn/ 前言 生产者和消费者问题是线程模型中的经典问题:...
  • weixin_38864718
  • weixin_38864718
  • 2017-07-11 13:52:02
  • 273

C++11实现简单生产者消费者模式

当前C++11已经实现了多线程、互斥量、条件变量等异步处理函数,并且提供了诸如sleep之类的时间函数,所以后面使用C++开发这一块的时候完全可以实现跨平台,无需在windows下写一套然后又在lin...
  • dailongjian2008
  • dailongjian2008
  • 2016-11-16 11:21:04
  • 3586

一看就懂系列之 php中的生产者and消费者模式

前言在工作中常常听到某某大牛之间的交谈会涉及到,xx消费者啊啥的,到底什么大牛之间讲的是什么? 这篇文章主要解决三个问题: 1.到底什么是生产者和消费者,以及它们之间的故事 2.它们之间靠什么交...
  • u011957758
  • u011957758
  • 2016-04-13 00:37:39
  • 1758
    个人资料
    等级:
    访问量: 148
    积分: 108
    排名: 142万+
    文章分类
    文章存档