注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

北漂的小羊

Java编程,开发者,程序员,软件开发,编程,代码。新浪微博号:IT国子监

 
 
 

日志

 
 
关于我

在这里是面向程序员的高品质IT技术学习社区,是程序员学习成长的地方。让我们更好地用技术改变世界。请关注新浪微博号: IT国子监(http://weibo.com/itguozijian)

网易考拉推荐

生产消费模型  

2013-03-02 14:05:18|  分类: 软件开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

“生产者-消费者-仓储”模型,包含三种角色:

1.生产者

2.消费者

3.仓库

 

离开了仓储,生产者消费者模型就显得没有说服力了。

 

对于此模型,应该明确一下几点:
1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。


生产者/消费者模型是最基本的并发协作模型,是所有并发协作的基础。可以这么说,其他的并发协作都是供求关系模型的变种。生产者,消费者之间的供求关系可以简单的 使用管道来构造。让我们看两者之间的行为模式: *生产/消费模型:消费者如果无消费对象,就会阻塞直到有消费对象到达;一个消费对象仅供一个消费者消费。 *BlockingQueue: 如果队列为空,则读取操作将会阻塞直至队列有新的内容到达;队列中对象一旦被读取,将从队列中移走。 由此可见,阻塞队列天然符合生产/消费模型的供求行为模式。当遇到一个线程要产生数据而另一个线程要处理数据时,这就是生产者消费者的关系。生产者在生产数据以后可以直接调用消费者处理数据,也可以将生产出来的数据,放到缓冲区中,等待消费者在缓冲区中取出数据然后再处理。第一种算是同步执行的,生产者将数据产生之后等待消费者将数据处理然后进行下一个数据的生产,当消费者处理数据的时间很长,那么会直接影响到生产者的效率。第二种方法算是异步的,当生产者将数据产生以后,将数据存储到一个缓冲区中,然后当消费者要处理数据时,会直接到缓冲区中去数据。当缓冲区中没有数据时,那么消费者就要等待生产者生产数据,当缓冲区中的数据存满时,那么生产者就要先等待消费者先处理一部分数据。

针对上面的描述的异步通信的场景创建两个类:Producer(生产者)和Consumer(消费者),其中生产者负责产生数据,且仅在缓冲区未满是产生数据;消费者负责处理数据,且仅在缓冲区不空是产生数据。

Java代码 
  1. /** 
  2.  * 生产者 
  3.  */  
  4. public class Producer implements Runnable{  
  5.  ThreadInter ti = null;  
  6.  public Producer(ThreadInter ti){  
  7.   this.ti = ti;  
  8.  }  
  9.   
  10.  public void run(){  
  11.   for(int i=0;i<10;i++){  
  12.    Cola cola = new Cola(i);  
  13.    ti.push(cola);  
  14.    System.out.println("生产了:"+cola);  
  15.    try{  
  16.     Thread.sleep(300);  
  17.    }catch(Exception e){  
  18.     e.printStackTrace();  
  19.    }  
  20.   }  
  21.  }  
  22.   
  23. }  
  24.   
  25.   
  26. /**  

 

Java代码 
  1.  * 消费者  
  2.  */  
  3. public class Consumer implements Runnable{  
  4.  ThreadInter ti = null;  
  5.  public Consumer(ThreadInter ti){  
  6.   this.ti = ti;  
  7.  }  
  8.   
  9.  public void run(){  
  10.   for(int i=0;i<10;i++){  
  11.    Cola cola = ti.pop();  
  12.    System.out.println("消费了:"+cola);  
  13.    try{  
  14.     Thread.sleep(600);  
  15.    }catch(Exception e){  
  16.     e.printStackTrace();  
  17.    }  
  18.   }  
  19.  }  
  20. }  

 还有一个Cola角色类,代表生产的商品

Java代码 
  1. public class Cola{  
  2.  private int id;  
  3.  public Cola(int id){  
  4.   this.id = id;  
  5.  }  
  6.  public String toString(){  
  7.   return "Cola:"+id;  
  8.  }  
  9. }  

 还需要创建一个处理缓冲区的类,同时处理线程是否生产和消费,线程之间的通信

Java代码 
  1. public class ThreadInter{  
  2.  private int index = 0;  
  3.  Cola[] colas = new Cola[6];  
  4.  //将cola加入缓存数组中  
  5.  public synchronized void push(Cola cola){  
  6.   System.out.println("生产index:"+index);  
  7.   while(index == colas.length){  
  8.    try{  
  9.     this.wait();  
  10.    }catch(Exception e){  
  11.     e.printStackTrace();  
  12.    }  
  13.   }  
  14.   this.notify();  
  15.   colas[index] = cola;  
  16.   index++;  
  17.  }  
  18.  //将cola取出  
  19.  public synchronized Cola pop(){  
  20.   System.out.println("消费index:"+index);  
  21.   while(index==0){  
  22.    try{  
  23.     this.wait();  
  24.    }catch(Exception e){  
  25.     e.printStackTrace();  
  26.    }  
  27.   }  
  28.   this.notify();  
  29.   index--;  
  30.   return colas[index];  
  31.  }  
  32. }  

 最后测试主类

Java代码 
  1. public class Main{  
  2.  public static void main(String []args) {  
  3.         ThreadInter ti=new ThreadInter();  
  4.   Producer p=new Producer(ti);  
  5.      Consumer c=new Consumer(ti);     
  6.   new Thread(p).start();  
  7.      new Thread(c).start();  
  8.  }  
  9. }  
  评论这张
 
阅读(419)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016