多线程之生产者消费者问题

生产者消费者问题介绍

生产者消费者问题是一个经典的多线程同步问题。该问题描述了两个进程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是不断的生成数据,而与此同时,消费者则不断消耗这些数据。该问题的关键就是要保证当生产者生产了产品后,若消费者还没有消费此产品,则生产者停止生产并等待,直到消费者消费了此产品;当消费者消费了产品后,若生产者还没有及时生产新的产品,则消费者停止消费并等待,直到生产者生产了新产品。

存在的问题

  • 当生产者比消费者快时,消费者会漏掉一部分数据
  • 当消费者比生产者快时,消费者会取走重复的数据

使用 wait() 和 notify() 方法

wait():当缓冲区已满 / 空时,生产者或消费者线程停止自己的执行,释放锁,使自己处于等待状态,让其它线程执行。

notify():当生产者或消费者向缓冲区放入或取出一个产品时,向其他等待的线程发出通知,同时释放锁,使自己处于等待状态,让其它线程执行。

 1 public class Demo04_生成者消费者 {
 2 
 3     public static void main(String[] args) {
 4         new Producer().start();
 5         new Consumer().start();
 6     }
 7 
 8     private static List<Integer> hamburgers  = new ArrayList<Integer>();
 9 
10     private static class Producer extends Thread{ //生产者
11 
12         int i=0;
13 
14         public void run() {
15 
16             while(true){
17                 if(hamburgers.size()<10){
18                     hamburgers.add(i);  // 生产
19                     System.out.println("生产汉堡:  "+i);
20                     i++;
21 
22                     synchronized (hamburgers) {
23                         hamburgers.notifyAll();
24                     }
25 
26                 }else{
27                     synchronized (hamburgers) {
28                         try {
29                             hamburgers.wait();
30                         } catch (InterruptedException e) {
31                             e.printStackTrace();
32                         }
33                     }
34 
35                 }
36 
37                 try {
38                     Thread.sleep(200);
39                 } catch (InterruptedException e) {
40                     e.printStackTrace();
41                 }
42             }
43         }
44     }
45 
46     private static class Consumer extends Thread{//消费者
47         public void run() {
48             while(true){
49                 if(hamburgers.size()>0){
50                     System.out.println("消费汉堡:  "+hamburgers.remove(0));  // 消费
51 
52                     synchronized (hamburgers) {
53                         hamburgers.notifyAll();
54                     }
55 
56                 }else{
57                     synchronized (hamburgers) {
58 
59                         try {
60                             hamburgers.wait();
61                         } catch (InterruptedException e) {
62                             // TODO Auto-generated catch block
63                             e.printStackTrace();
64                         }
65                     }
66                 }
67 
68                 try {
69                     Thread.sleep(200);
70                 } catch (InterruptedException e) {
71                     e.printStackTrace();
72                 }
73             }
74         }
75     }
76 }

 

posted @ 2022-03-09 23:15  MMarshall  阅读(144)  评论(0编辑  收藏  举报