生产者消费者问题
1、产品池,生产者生产产品,放入池中;消费者从池中消费产品
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.test.producerandconsumer; 2 3 /** 4 * 产品池,生产者生产产品,放入池中;消费者从池中消费产品 5 * @author tim 6 */ 7 public class DataPool 8 { 9 int value = 0;// 产品池中产品总个数 10 boolean isEmpty = true;// 判断产品池的状态是否为空 11 12 /** 13 * 生产者生产产品 14 * 同步方法,需要DataPool的锁才能执行 15 * @param v 每次生产的产品个数 16 */ 17 public synchronized void put(int v) 18 { 19 // 如果产品没有被消费完,则生产者等待,消费者可以消费 20 if (!isEmpty) 21 { 22 try 23 { 24 System.out.println("产品没有被消费完,生产者等待,消费者开始消费"); 25 wait();// 当前正在这个对象访问的线程进入等待状态,当前线程停止完,直到notify唤醒,同时释放锁 26 // 与sleep不同,sleep锁不释放 27 } 28 catch (Exception e) 29 { 30 e.printStackTrace(); 31 } 32 } 33 else// 产品消费完,则生产者开始生产,消费者等待 34 { 35 value += v;// 求产品池中产品总个数 36 isEmpty = false;// 产品池状态非空 37 System.out.println("生产者共生产了数量为:" + value + "的产品"); 38 notify();// 通知当前正在这个对象上wait的线程执行,消费者消费 39 } 40 } 41 42 /** 43 * 消费者消费产品 44 * 同步方法,需要DataPool的锁才能执行 45 * @return 46 */ 47 public synchronized int get() 48 { 49 // 消费者消费前,如果产品池中的产品已经被消费完,则消费者等待,生产者生产产品 50 if (isEmpty) 51 { 52 try 53 { 54 System.out.println("产品已经被消费完,消费者等待,生产者开始生产"); 55 wait();// 消费者等待 56 } 57 catch (Exception e) 58 { 59 e.printStackTrace(); 60 } 61 } 62 else// 产品未消费完,则开始消费 63 { 64 value--; 65 if (value < 1) 66 { 67 isEmpty = true; 68 } 69 System.out.println("消费者消费一个,剩余:" + value); 70 notify();// 消费者消费后,通知生产者生产 71 } 72 return value; 73 } 74 75 }
2、生产者,产生产品
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.test.producerandconsumer; 2 3 /** 4 * 生产者,产生产品 5 * 持有产品池的引用,向产品池中放入产品。 6 * 依次放入50个产品 7 * @author tim 8 * @date 2016-04-27 9 */ 10 public class Producer extends Thread 11 { 12 DataPool p;// 存放产品 13 14 public Producer(DataPool p) 15 { 16 this.p = p; 17 } 18 19 public void run() 20 { 21 for (int i = 1; i < 50; i++) 22 { 23 p.put(i);// 放入产品 24 } 25 } 26 }
3、消费者,消费产品
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.test.producerandconsumer; 2 3 /** 4 * 消费者,消费产品 5 * 持有产品池的引用,从产品池中获取产品。 6 * 继承Thread,覆盖run方法,在run方法中不停的获取产品。 7 * @author tim 8 * @date 2016-04-27 9 */ 10 public class Consumer extends Thread 11 { 12 DataPool p;// 产品 13 14 public Consumer(DataPool p) 15 { 16 this.p = p; 17 } 18 19 public void run() 20 { 21 while (true) 22 { 23 p.get();// 获取产品 24 } 25 } 26 }
4、测试类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.test.producerandconsumer; 2 3 public class ProducerAndConsumer 4 { 5 public static void main(String[] args) 6 { 7 DataPool pool = new DataPool(); 8 9 Producer p1 = new Producer(pool); 10 Consumer c1 = new Consumer(pool); 11 12 p1.start(); 13 c1.start(); 14 } 15 }
测试结果: