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

 

在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(): enter
pool-1-thread-1【要消费的产品数量】: 30 【库存量】:0 暂时不能执行消费任务!
pool-1-thread-1 enter await
pool-1-thread-2【要消费的产品数量】: 50 【库存量】:0 暂时不能执行消费任务!
pool-1-thread-2 enter await
pool-1-thread-4 【已经生产产品数】:10 【现仓储量为】:10
test_threadpool_runnal(): exit
pool-1-thread-5 【已经生产产品数】:20 【现仓储量为】:30
pool-1-thread-3【要消费的产品数量】: 80 【库存量】:30 暂时不能执行消费任务!
pool-1-thread-3 enter await
pool-1-thread-1 【已经消费产品数】: 30 【现仓储量为】:0
pool-1-thread-1 【已经生产产品数】:50 【现仓储量为】:50
pool-1-thread-1 【已经生产产品数】:60 【现仓储量为】:110
pool-1-thread-1 【已经生产产品数】:70 【现仓储量为】:180
pool-1-thread-2 【已经消费产品数】: 50 【现仓储量为】:130
pool-1-thread-4 【已经生产产品数】:30 【现仓储量为】:160
pool-1-thread-5 【已经生产产品数】:40 【现仓储量为】:200
pool-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();
  
 }
}

你可能感兴趣的:(用Java实现 生产者/消费者问题)