Producer-Consumer Pattern

Producer-ConsumerPattern

Producer是“生产者”的意思,是指产生数据的线程。而Consumer是“消费者”的意思,意指使用数据的线程。

生产者必须将数据安全地交给消费者。虽然只是这样的问题,但当生产者与消费者在不同线程上运行时,两者的处理速度差将是最大的问题。当消费者要取数据时生产者还没建立出数据,或是生产者建立出数据时消费者的状态还没办法接收数据等等。

Producer-ConsumerPattern是在生产者与消费者之间加入一个“桥梁参与者”。以这个桥梁参与者与缓冲线程之间的处理速度差。

范例程序

Main 操作测试用的类

Producer模拟生产者生产数据

Consumer模拟消费者使用数据

DataNumber产生数据编号

Buffer模拟缓冲区

Buffer代码:

public class Buffer {

 

  private String[] buffer;// 模拟缓冲区

 

  private int count;// 缓冲区中数据的个数

 

  private int head;// 下一个取走数据的地方

 

  private int tail;// 下一个放置数据的地方

 

  public Buffer(int size) {

      buffer = new String[size];

 

      count = 0;

      head = 0;

      tail = 0;

  }

 

  public synchronized void put(String data)throws InterruptedException {

      while (count >= buffer.length) {

         wait();

      }

 

      buffer[tail] = data;

 

      Thread.sleep(1000);

 

      System.out.println(Thread.currentThread().getName()+ " 放入数据: " + data);

 

      tail = (tail + 1) % buffer.length;

 

      count++;

 

      notifyAll();

  }

 

  public synchronized String get() throwsInterruptedException {

      while (count <= 0) {

         wait();

      }

 

      String data = buffer[head];

 

      head = (head + 1) % buffer.length;

 

      count--;

 

      notifyAll();

 

      Thread.sleep(1000);

 

      System.out.println(Thread.currentThread().getName()+ " 取出数据: " + data);

 

      return data;

  }

 

}

DataNumber代码:

public final classDataNumber {

 

  private static int number = 1;

 

  public synchronized static int getNumber() {

      return number++;

  }

 

}

Producer代码:

public class Producerextends Thread {

 

  private Buffer buffer;

 

  public Producer(Buffer buffer, StringthreadName) {

      super(threadName);

 

      this.buffer = buffer;

  }

 

  @Override

  public void run() {

      while (true) {

         try {

             String data = "Data No."

                    +String.valueOf(DataNumber.getNumber());

             buffer.put(data);

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

      }

  }

}

Consumer代码:

public class Consumerextends Thread {

 

  private Buffer buffer;

 

  public Consumer(Buffer buffer, StringthreadName) {

      super(threadName);

 

      this.buffer = buffer;

  }

 

  @Override

  public void run() {

      while (true) {

         try {

             buffer.get();

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

      }

  }

}

Main代码:

public class Main {

 

  /**

   *@param args

   */

  public static void main(String[] args) {

 

      Buffer buffer = new Buffer(5);

     

      new Producer(buffer,"Producer1").start();

      new Producer(buffer,"Producer2").start();

      new Producer(buffer,"Producer3").start();

     

      new Consumer(buffer,"Consumer1").start();

      new Consumer(buffer,"Consumer2").start();

  }

 

}

从运行结果可以看出:消费者按生产者放入数据的顺序从缓冲区中取出数据。

要以什么顺序传递Data

Ø  队列——最先收到的先传

最常见的做法,是把最先收到的传出去。我们将这种方法称为FIFOFirst In First Out),先进先出或称为队列(Queue)。

Ø  堆栈——最后收到的先传

与队列相反的,最后收到的Data先传出去。这称之为LIFOLast In First Out),后进先出,又称为堆栈(stack)

Ø  优先队列——“优先”的东西先传

Data以某些条件给予优先次序,而优先性高的先传给Consumer参与者。决定优先次序的方法有很多,依应用情况而定。

队列、堆栈可以说是优先队列的特例,Data收到时间较早、优先性高的优先队列称为队列,而Data收到时间较晚、优先性高的优先队列称为堆栈。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值