瘦鱼-博客

生产者消费者问题

1、产品池,生产者生产产品,放入池中;消费者从池中消费产品

 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 }
DataPool

2、生产者,产生产品

 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 }
Producer

3、消费者,消费产品

 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 }
Consumer

4、测试类

 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 }
ProducerAndConsumer

测试结果:

 

posted @ 2016-12-05 21:54  瘦鱼  阅读(200)  评论(0编辑  收藏  举报