生产者-消费者模式是一个经典的多线程设计模式,它为多线程的协作提供了良好的解决方案。在生产者-消费者模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程。生产者线程负责提交用户请求,消费者线程负责处理用户请求。生产者和消费者之间通过共享内存缓冲区进行通信。
生产者-消费者模式中的内存缓冲区的主要功能是数据在多线程间的共享。此外,通过该缓冲区,可以缓解生产者和消费者之间的性能差。
1. 馒头
这里采用了面向对象的设计思想,馒头在整个程序中自然是一个类,其Java代码如下。
class ManTou { int id; ManTou(int id) { this.id = id; } public String toString() { return "ManTou: " + id; } }
2. 篮子(装馒头)
篮子是有容量的,因此篮子类需要有一个变量表示容量;篮子至少还有取和装馒头这两个功能,其Java代码如下:
class SyncStack { //篮子 int index = 0; ManTou[] arrMT = new ManTou[6]; //假设这个篮子只能装6个馒头 public synchronized void push(ManTou wt) { //装馒头 while(index == arrMT.length) { //篮子满了 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); //如果取馒头的wait了,则通知他醒来 arrMT[index] = wt; index ++; } public synchronized ManTou pop() { //取馒头 while(index == 0) { //篮子空了 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); //如果产馒头的wait了,则通知他醒来 index --; return arrMT[index]; } }
3. 生产者(生产馒头)
生产者需要获取篮子这个对象,而且篮子不能是自己创建的。其Java代码如下:
class Producer implements Runnable { //生产者 SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { //一共要生成20个 ManTou wt = new ManTou(i); ss.push(wt); System.out.println("生产了:" + wt); try { //生成一个睡1秒,便于观察 Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } }
4. 消费者(吃馒头)
消费需要获取篮子这个对象,而且这个对象必须与生产者获取的篮子是同一个对象,这样才能信息共享。其Java代码如下:
class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<20; i++) { //一共要吃20个 ManTou wt = ss.pop(); System.out.println("消费了:" + wt); } } }
5. 测试运行
主函数Java代码如下:
public class ProducerConsumer { public static void main(String[] args) { SyncStack ss = new SyncStack(); //定义篮子 Producer p = new Producer(ss); //定义生产者 Consumer c = new Consumer(ss); //定义消费者 new Thread(p).start(); new Thread(c).start(); } }
转载地址:http://blog.csdn.net/ghuil/article/details/41044257
时间: 2024-11-17 01:35:03