用Java实现 生产者/消费者问题

来源:互联网 发布:淘宝大学哪个老师最好 编辑:程序博客网 时间:2024/06/04 18:52

 

在Java中一共有四种方法支持同步,其中前三个是同步方法,一个是管道方法。

(1)wait() / notify()方法

(2)await() / signal()方法

(3)BlockingQueue阻塞队列方法

(4)PipedInputStream / PipedOutputStream

本人编写的JAVA代码只实现了最常用的前三种。JAVA代码在 eclipse 调试通过。

有一篇文章也不错,可以去看看

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

 

代码如下:

 

package threadSync;
import java.util.LinkedList;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  
/** * 仓库类Storage的父类,做接口用,其子类必须重载这两个方法 *  */ class SupperStorage { public void produce(int num){ System.out.println("SupperStorage::produce()"); }; public void consume(int num){  System.out.println("SupperStorage::consume()");  }; }
 /**  * 仓库类Storage3实现缓冲区  with LinkedBlockingQueue  *   */  class Storage3 extends SupperStorage {  // 仓库最大存储量  private final int MAX_SIZE = 200;  // 仓库存储的载体  private LinkedBlockingQueue<Object>list=new LinkedBlockingQueue<Object>(MAX_SIZE);
  // 生产num个产品  public void produce(int num)  {   // 如果仓库 is full   if (list.size() == MAX_SIZE)   {    System.out.println("【库存量】 is full: " + MAX_SIZE + " 暂时不能执行生产任务!");   }
   // 生产条件满足情况下,生产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("【库存量】 is empty, 暂时不能执行消费任务!");   }
   // 消费条件满足情况下,消费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;  } }   /**  * 仓库类Storage2实现缓冲区 with await() / signal()  *   */ class Storage2 extends SupperStorage {  // 仓库最大存储量  private final int MAX_SIZE = 200;  // 仓库存储的载体  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个产品  public void produce(int num)  {   // 获得锁   lock.lock();
   // 如果仓库剩余容量不足   while (list.size() + num > MAX_SIZE)   {    System.out.println("【要生产的产品数量】: " + num + " 【库存量】:" + list.size()            + " 暂时不能执行生产任务!");    try    {     // 由于条件不满足,生产阻塞     System.out.println(Thread.currentThread().getName()+" enter await");     full.await();    }    catch (InterruptedException e)    {     e.printStackTrace();    }   }
   // 生产条件满足情况下,生产num个产品   for (int i = 1; i <= num; ++i)   {    list.add(new Object());   }
   System.out.println(Thread.currentThread().getName() + " 【已经生产产品数】:" + num + " 【现仓储量为】:" + list.size());
   // 唤醒其他所有线程   full.signalAll();   empty.signalAll();
   // 释放锁   lock.unlock();  }
  // 消费num个产品  public void consume(int num)  {   // 获得锁   lock.lock();
   // 如果仓库存储量不足   while (list.size() < num)   {    System.out.println( Thread.currentThread().getName() + "【要消费的产品数量】: " + num + " 【库存量】:" + list.size()            + " 暂时不能执行消费任务!");    try    {     // 由于条件不满足,消费阻塞     System.out.println(Thread.currentThread().getName()+" enter await");     empty.await();    }    catch (InterruptedException e)    {     e.printStackTrace();    }   }
   // 消费条件满足情况下,消费num个产品   for (int i = 1; i <= num; ++i)   {    list.remove();   }
   System.out.println(Thread.currentThread().getName() + " 【已经消费产品数】: " + num + " 【现仓储量为】:" + list.size());
   // 唤醒其他所有线程   full.signalAll();   empty.signalAll();
   // 释放锁   lock.unlock();  }
  // set/get方法  public int getMAX_SIZE()  {   return MAX_SIZE;  }
  public LinkedList<Object> getList()  {   return list;  }
  public void setList(LinkedList<Object> list)  {   this.list = list;  } }  // Storage with wait() / notify()  class Storage extends SupperStorage { // 仓库最大存储量 private final int MAX_SIZE = 200;
 // 仓库存储的载体 private LinkedList<Object> list = new LinkedList<Object>();
 // 生产num个产品 public void produce(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();    }   }
   // 生产条件满足情况下,生产num个产品   for (int i = 1; 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; }}   /*  * 生产者类Producer继承线程类Thread    *    */   class Producer extends Thread   {       // 每次生产的产品数量        private int num;          // 所在放置的仓库        private SupperStorage storage;          // 构造函数,设置仓库        public Producer(SupperStorage storage)       {           this.storage = storage;       }          // 线程run函数        public void run()       {           produce(num);       }          // 调用仓库Storage的生产函数        public void produce(int num)       {           storage.produce(num);       }          // get/set方法        public int getNum()       {           return num;       }          public void setNum(int num)       {           this.num = num;       }          public SupperStorage getStorage()       {           return storage;       }          public void setStorage(SupperStorage storage)       {           this.storage = storage;       }   }  
 class Producer2 implements Runnable   {       // 每次生产的产品数量        private int num;          // 所在放置的仓库        private SupperStorage storage;          // 构造函数,设置仓库        public Producer2(SupperStorage storage)       {           this.storage = storage;       }          // 线程run函数        public void run()       {           produce(num);       }          // 调用仓库Storage的生产函数        public void produce(int num)       {           storage.produce(num);       }          // get/set方法        public int getNum()       {           return num;       }          public void setNum(int num)       {           this.num = num;       }          public SupperStorage getStorage()       {           return storage;       }          public void setStorage(SupperStorage storage)       {           this.storage = storage;       }   }  
 class Consumer extends Thread{ // 每次消费的产品数量 private int num;
 // 所在放置的仓库 private SupperStorage storage;
 // 构造函数,设置仓库 public Consumer(SupperStorage 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 SupperStorage getStorage() {  return storage; }
 public void setStorage(SupperStorage storage) {  this.storage = storage; }}  class Consumer2 implements Runnable {  // 每次消费的产品数量  private int num;
  // 所在放置的仓库  private SupperStorage storage;
  // 构造函数,设置仓库  public Consumer2 (SupperStorage 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 SupperStorage getStorage()  {   return storage;  }
  public void setStorage(SupperStorage storage)  {   this.storage = storage;  } }/** * 测试类Test *  */public class mythreadsync{ //this method is used to test thread generated via class Thread  public void test_thread() {     System.out.println("test_thread(): enter");   //SupperStorage storage = new Storage3();   //SupperStorage storage = new Storage();   SupperStorage storage = new Storage2();   // 生产者对象   Producer p1 = new Producer(storage);   Producer p2 = new Producer(storage);   Producer p3 = new Producer(storage);   Producer p4 = new Producer(storage);   Producer p5 = new Producer(storage);   Producer p6 = new Producer(storage);   Producer p7 = new Producer(storage);
   // 消费者对象   Consumer c1 = new Consumer(storage);   Consumer c2 = new Consumer(storage);   Consumer c3 = new Consumer(storage);
   // 设置生产者产品生产数量   p1.setNum(10);   p2.setNum(10);   p3.setNum(10);   p4.setNum(10);   p5.setNum(10);   p6.setNum(10);   p7.setNum(80);
   // 设置消费者产品消费数量   c1.setNum(50);   c2.setNum(20);   c3.setNum(30);
   // 线程开始执行   c1.start();   c2.start();   c3.start();      p1.start();   p2.start();   p3.start();   p4.start();   p5.start();   p6.start();   p7.start();   System.out.println("test_thread(): exit"); }  //this method is used to test threads implementing interface runnable  public void test_thread_runnable() {    System.out.println("test_thread_runnable(): enter");  SupperStorage storage = new Storage2();  // 生产者对象    Producer2 p1 = new Producer2(storage);  Producer2 p2 = new Producer2(storage);  Producer2 p3 = new Producer2(storage);  Producer2 p4 = new Producer2(storage);  Producer2 p5 = new Producer2(storage);  Producer2 p6 = new Producer2(storage);  Producer2 p7 = new Producer2(storage);
  // 消费者对象  Consumer2 c1 = new Consumer2(storage);  Consumer2 c2 = new Consumer2(storage);  Consumer2 c3 = new Consumer2(storage);
  // 设置生产者产品生产数量  p1.setNum(10);  p2.setNum(10);  p3.setNum(10);  p4.setNum(10);  p5.setNum(10);  p6.setNum(20);  p7.setNum(80);
  // 设置消费者产品消费数量  c1.setNum(50);  c2.setNum(20);  c3.setNum(30);
  // 线程开始执行  new Thread(c1,"consumer 1").start();  new Thread(c2,"consumer 2").start();  new Thread(c3,"consumer 3").start();    new Thread(p1,"producer 1").start();  new Thread(p2,"producer 2").start();  new Thread(p3,"producer 3").start();  new Thread(p4,"producer 4").start();  new Thread(p5,"producer 5").start();  new Thread(p6,"producer 6").start();  new Thread(p7,"producer 7").start();  System.out.println("test_thread_runnable(): exit");    }  //this method is used to test threads pool for thread implementing interface runnable   public void test_threadpool_runnal() {      System.out.println("test_threadpool_runnal(): enter");   SupperStorage storage = new Storage2();      // 生产者对象   Producer2 p1 = new Producer2(storage);   Producer2 p2 = new Producer2(storage);   Producer2 p3 = new Producer2(storage);   Producer2 p4 = new Producer2(storage);   Producer2 p5 = new Producer2(storage);   Producer2 p6 = new Producer2(storage);   Producer2 p7 = new Producer2(storage);
   // 消费者对象   Consumer2 c1 = new Consumer2(storage);   Consumer2 c2 = new Consumer2(storage);   Consumer2 c3 = new Consumer2(storage);
   // 设置生产者产品生产数量   p1.setNum(10);   p2.setNum(20);   p3.setNum(30);   p4.setNum(40);   p5.setNum(50);   p6.setNum(60);   p7.setNum(70);
   // 设置消费者产品消费数量   c1.setNum(30);   c2.setNum(50);   c3.setNum(80);      ExecutorService pool=Executors.newFixedThreadPool(5);//创建一个固定大小为5的线程池  
   // 线程开始执行   // 3 consumers   pool.submit(c1);   pool.submit(c2);   pool.submit(c3);      // 7 producers   pool.submit(p1);   pool.submit(p2);   pool.submit(p3);   pool.submit(p4);   pool.submit(p5);   pool.submit(p6);   pool.submit(p7);/* * it shows, at most, only 5 working threads in parallel even if 10 tasks submitted. * test_threadpool_runnal(): enterpool-1-thread-1【要消费的产品数量】: 30 【库存量】:0 暂时不能执行消费任务!pool-1-thread-1 enter awaitpool-1-thread-2【要消费的产品数量】: 50 【库存量】:0 暂时不能执行消费任务!pool-1-thread-2 enter awaitpool-1-thread-4 【已经生产产品数】:10 【现仓储量为】:10test_threadpool_runnal(): exitpool-1-thread-5 【已经生产产品数】:20 【现仓储量为】:30pool-1-thread-3【要消费的产品数量】: 80 【库存量】:30 暂时不能执行消费任务!pool-1-thread-3 enter awaitpool-1-thread-1 【已经消费产品数】: 30 【现仓储量为】:0pool-1-thread-1 【已经生产产品数】:50 【现仓储量为】:50pool-1-thread-1 【已经生产产品数】:60 【现仓储量为】:110pool-1-thread-1 【已经生产产品数】:70 【现仓储量为】:180pool-1-thread-2 【已经消费产品数】: 50 【现仓储量为】:130pool-1-thread-4 【已经生产产品数】:30 【现仓储量为】:160pool-1-thread-5 【已经生产产品数】:40 【现仓储量为】:200pool-1-thread-3 【已经消费产品数】: 80 【现仓储量为】:120 */
   pool.shutdown();
   System.out.println("test_threadpool_runnal(): exit");     }   public static void main(String[] args) {  mythreadsync my = new mythreadsync();  //my.test_thread();  my.test_threadpool_runnal();  //my.test_thread_runnable();   }}
0 0