多线程生产者消费者实例

  • 目的

        生产者和消费者实例主要是练习synchronized、wait、notify或notifyAll、join等的使用,实际感受他们的用途。这例子自己随意写的,也没想到写得多么完善,只是为了练习。大家将就看看吧,哈哈!


  • 食物类
 1 package thread.producer.customer;
 2 
 3 public class Food {
 4 
 5     private String name;
 6 
 7     public String getName() {
 8         return name;
 9     }
10 
11     public void setName(String name) {
12         this.name = name;
13     }
14     
15     
16 }
  • 盘子类
 1 package thread.producer.customer;
 2 
 3 
 4 public class Plate {
 5 
 6     //如果是0,表示盘子内没东西
 7     private int index;
 8     private volatile boolean foodIsFinish = false;
 9     
10     /**
11      * 向盘子内添加食物,生产者添加食物时,消费者是不能吃食物的,小心被烫到,哈哈
12      * @param food
13      */
14     public synchronized void addFood(Food food) {
15         index++;
16         System.out.println("盘子内增加了" + food.getName());
17         notifyAll();
18     }
19     
20     public synchronized void eatFood(String chihuo) throws InterruptedException{
21         //盘子中没有食物,不代表生产者已经将食物生产完,所以此处要判断生产者是否将食物生产完
22         //只有在盘子没有食物,同时生产者生产完所有食物的时候,该线程才什么都不做,直到线程结束
23         while(index == 0 && !foodIsFinish) {
24 //            System.out.println(chihuo + "在等待食物");
25             wait();
26         }
27         if(index > 0) {
28             index--;
29             System.out.println("盘子内被"+chihuo+"吃掉");
30         }
31     }
32     
33     public synchronized boolean isEmpty() {
34         return index == 0;
35     }
36     
37     public synchronized void setFoodIsFinish(){
38         this.foodIsFinish = true;
39     }
40     
41     public synchronized boolean getFoodIsFinish() {
42         return foodIsFinish;
43     }
44     /**
45      * 等待生产者线程执行完毕,该方法不能为同步方法
46      * @param threads
47      * @throws InterruptedException
48      */
49     public void waitProducerFinish(Thread producerThread) throws InterruptedException {
50         producerThread.join();
51         System.out.println("生产者生产食物完毕");
52         //每个线程结束后,唤醒其他线程,因为有可能出现生产者线程执行完毕,而消费者线程在等待状态,这样就会出现消费者线程一直处于等待状态
53         //这里只能用同步代码块,不能将整个方法进行同步
54         synchronized(this) {
55             setFoodIsFinish();
56             //notify,notifyAll方法必须在同步方法或同步代码块内,wait方法也一样
57             notifyAll();
58         }
59     }
60     
61     /**
62      * 该方法不能为同步方法
63      * @param threads
64      * @throws InterruptedException
65      */
66     public void waitCustomerFinish(Thread[] threads) throws InterruptedException {
67         for(int i = 0; i < threads.length; i++) {
68             threads[i].join();
69         }
70         System.out.println("消费者线程结束");
71     }
72 }
  • 消费者线程
 1 package thread.producer.customer;
 2 
 3 public class CustomerThread implements Runnable{
 4     
 5     private Plate plate;
 6     private String chihuo;
 7     
 8     public CustomerThread(Plate plate, String chihuo) {
 9         this.plate = plate;
10         this.chihuo = chihuo;
11     }
12 
13     @Override
14     public void run() {
15         try {
16             //判断盘子是否为空以及生产者是否已经生产食物完毕
17             //只要在盘子为空或者生产者还有食物生产时,才不跳出循环
18             //这样判断是防止生产者还有食物生产,恰好盘子中无食物,线程退出的不正确情况出现
19             while(!plate.isEmpty() || !plate.getFoodIsFinish()) {
20 //                System.out.println(chihuo + "准备吃食物");
21                 plate.eatFood(chihuo);
22             }
23         } catch (InterruptedException e) {
24             e.printStackTrace();
25         }
26     }
27 
28 }
View Code
  • 生产者线程

 

 1 package thread.producer.customer;
 2 
 3 public class ProducerThread implements Runnable{
 4     
 5     private Plate plate;
 6     
 7     public ProducerThread(Plate plate){
 8         this.plate = plate;
 9     }
10 
11     @Override
12     public void run() {
13         String[] foodType = {"apple","banana","pear","plum","grape","drumstick","hamburg","pineapple","staswberry","orange"};
14         for(int i = 0; i < 100; i++) {
15             int random = (int) (Math.random() * 10);
16             Food food = new Food();
17             food.setName(foodType[random]);
18 //            System.out.println("生产者准备添加食物");
19             plate.addFood(food);
20         }
21     }
22 }
View Code

 

  • 测试类
 1 package thread.producer.customer;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         Plate plate = new Plate();
 7         Thread t1 = new Thread(new ProducerThread(plate));
 8         Thread t2 = new Thread(new CustomerThread(plate, "吃货1号"));
 9         Thread t3 = new Thread(new CustomerThread(plate, "吃货2号"));
10         t1.start();
11         t2.start();
12         t3.start();
13         Thread[] threads = new Thread[2];
14         threads[0] = t2;
15         threads[1] = t3;
16         try {
17             plate.waitProducerFinish(t1);
18             plate.waitCustomerFinish(threads);
19         } catch (InterruptedException e) {
20             e.printStackTrace();
21         }
22     }
23 
24 }
View Code

 

转载于:https://www.cnblogs.com/yuyuj/p/4524148.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值