生产者/消费者模式Java实现方式

来源:互联网 发布:lol比赛数据查询 编辑:程序博客网 时间:2024/06/06 21:42

使用Java实现生产者/消费者模式几种方法:

 1. wait()/notify()方法 2. await()/signal()方法 3. BlockingQueue阻塞队列方法

wait()/notify()方法:

public class Storage {    //存储的最大容量    private final int MAX_SIZE=10;    //存储的容器    private LinkedList<Object> list = new LinkedList<Object>();      /**     * 生产num个产品     * @param num     */    public void product(int num){        synchronized(list){            while(list.size()+num>MAX_SIZE){                  System.out.println("【要生产的产品数量】:" + num + "\t【库存量】:"                              + list.size() + "\t暂时不能执行生产任务!");                  try {                    list.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            for(int i=0;i<num;i++){                list.add(new Object());            }            System.out.println("【已经生产产品数】:" + num + "\t【现仓储量为】:" + list.size());              list.notifyAll();          }    }       // 消费num个产品      public void consume(int num)      {          // 同步代码段          synchronized (list)          {              // 如果仓库存储量不足              while (list.size() < num)              {                  System.out.println("【要消费的产品数量】:" + num + "\t【库存量】:"                          + list.size() + "\t暂时不能执行生产任务!");                  try                  {                      // 由于条件不满足,消费阻塞                      list.wait();                  }                  catch (InterruptedException e)                  {                      e.printStackTrace();                  }              }              // 消费条件满足情况下,消费num个产品              for (int i = 1; i <= num; ++i)              {                  list.remove();              }              System.out.println("【已经消费产品数】:" + num + "\t【现仓储量为】:" + list.size());              list.notifyAll();          }      }       // get/set方法      public LinkedList<Object> getList()      {          return list;      }      public void setList(LinkedList<Object> list)      {          this.list = list;      }      public int getMAX_SIZE()      {          return MAX_SIZE;      }  }public class Producer extends Thread  {      // 每次生产的产品数量      private int num;      // 所在放置的仓库      private Storage storage;      // 构造函数,设置仓库      public Producer(Storage storage)      {          this.storage = storage;      }      // 线程run函数      public void run()      {          produce(num);      }      // 调用仓库Storage的生产函数      public void produce(int num)      {          storage.product(num);      }      // get/set方法      public int getNum()      {          return num;      }      public void setNum(int num)      {          this.num = num;      }      public Storage getStorage()      {          return storage;      }      public void setStorage(Storage storage)      {          this.storage = storage;      }  }  public class Consumer extends Thread  {      // 每次消费的产品数量      private int num;      // 所在放置的仓库      private Storage storage;      // 构造函数,设置仓库      public Consumer(Storage storage)      {          this.storage = storage;      }      // 线程run函数      public void run()      {          consume(num);      }      // 调用仓库Storage的生产函数      public void consume(int num)      {          storage.consume(num);      }      // get/set方法      public int getNum()      {          return num;      }      public void setNum(int num)      {          this.num = num;      }      public Storage getStorage()      {          return storage;      }      public void setStorage(Storage storage)      {          this.storage = storage;      }  }  public class Test01 {     public static void main(String[] args)          {              // 仓库对象              Storage storage = new Storage();              // 生产者对象              Producer p1 = new Producer(storage);              Producer p2 = new Producer(storage);              Producer p3 = new Producer(storage);              // 消费者对象              Consumer c1 = new Consumer(storage);              Consumer c2 = new Consumer(storage);              Consumer c3 = new Consumer(storage);              // 设置生产者产品生产数量              p1.setNum(2);              p2.setNum(3);              p3.setNum(4);              // 设置消费者产品消费数量              c1.setNum(5);              c2.setNum(2);              c3.setNum(3);              // 线程开始执行              c1.start();              c2.start();              c3.start();              p1.start();              p2.start();              p3.start();          }  }

await()/signal()方法:
ArrayBlockingQueue也是使用两个监视器队列来实现的。

public class Storage {    //存储的最大容量    private final int MAX_SIZE=10;    //存储的容器    private LinkedList<Object> list = new LinkedList<Object>();      private  final Lock lock = new ReentrantLock();      // 仓库满的条件变量      private final Condition full = lock.newCondition();      // 仓库空的条件变量      private final Condition empty = lock.newCondition();      /**     * 生产num个产品     * @param num     */    public void product(int num){            lock.lock();            while(list.size()+num>MAX_SIZE){                  System.out.println("【要生产的产品数量】:" + num + "\t【库存量】:"                              + list.size() + "\t暂时不能执行生产任务!");                  try {                     full.await();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            for(int i=0;i<num;i++){                list.add(new Object());            }            System.out.println("【已经生产产品数】:" + num + "\t【现仓储量为】:" + list.size());              //唤醒消费队列            empty.signalAll();              // 释放锁              lock.unlock();      }     // 消费num个产品      public void consume(int num)      {          // 获得锁          lock.lock();          // 如果仓库存储量不足          while (list.size() < num)          {              System.out.println("【要消费的产品数量】:" + num + "\t【库存量】:" + list.size()                      + "\t暂时不能执行生产任务!");              try              {                  // 由于条件不满足,消费阻塞                  empty.await();              }              catch (InterruptedException e)              {                  e.printStackTrace();              }          }          // 消费条件满足情况下,消费num个产品          for (int i = 1; i <= num; ++i)          {              list.remove();          }          System.out.println("【已经消费产品数】:" + num + "\t【现仓储量为】:" + list.size());          //唤醒生产队列        full.signalAll();          // 释放锁          lock.unlock();      }       // get/set方法      public LinkedList<Object> getList()      {          return list;      }      public void setList(LinkedList<Object> list)      {          this.list = list;      }      public int getMAX_SIZE()      {          return MAX_SIZE;      }  }

BlockingQueue阻塞队列方法:
使用阻塞队列已经实现的消费者/生产者模式:
put()方法:类似于我们上面的生产者线程,容量达到最大时,自动阻塞。
take()方法:类似于我们上面的消费者线程,容量为0时,自动阻塞。

public class Storage  {      // 仓库最大存储量      private final int MAX_SIZE = 100;      // 仓库存储的载体      private LinkedBlockingQueue<Object> list = new LinkedBlockingQueue<Object>(              100);      // 生产num个产品      public void produce(int num)      {          // 如果仓库剩余容量为0          if (list.size() == MAX_SIZE)          {              System.out.println("【库存量】:" + MAX_SIZE + "/t暂时不能执行生产任务!");          }          // 生产条件满足情况下,生产num个产品          for (int i = 1; i <= num; ++i)          {              try              {                  // 放入产品,自动阻塞                  list.put(new Object());              }              catch (InterruptedException e)              {                  e.printStackTrace();              }              System.out.println("【现仓储量为】:" + list.size());          }      }      // 消费num个产品      public void consume(int num)      {          // 如果仓库存储量不足          if (list.size() == 0)          {              System.out.println("【库存量】:0/t暂时不能执行生产任务!");          }          // 消费条件满足情况下,消费num个产品          for (int i = 1; i <= num; ++i)          {              try              {                  // 消费产品,自动阻塞                  list.take();              }              catch (InterruptedException e)              {                  e.printStackTrace();              }          }          System.out.println("【现仓储量为】:" + list.size());      }      // set/get方法      public LinkedBlockingQueue<Object> getList()      {          return list;      }      public void setList(LinkedBlockingQueue<Object> list)      {          this.list = list;      }      public int getMAX_SIZE()      {          return MAX_SIZE;      }  }  

原文参考:

http://blog.csdn.net/monkey_d_meng/article/details/6251879/