线程通信应用---经典例题:生产者/消费者问题:

/**
* 经典例题:生产者/消费者问题:
* 生产者(Producer)将产品交给店员(clerk),而消费者(customer)从店员处取走产品,店员一次只能持有固定数量
* 产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者
* 继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
*
* 分析:
* 1.是否是多线程问题?是,生产者线程,消费者线程
* 2.是否有共享数据?是,店员(或产品)
* 3.如何解决线程的安全问题:同步机制,有三种方法
* 4.是否涉及到线程的通信?是
*
* 这里可能出现的问题:
* 生产者比消费者块时,消费者会漏掉一些数据没有取到
* 消费者比生产者块时,消费者会取相同的数据。
*
* @author fu jingchao
* @creat 2021/10/27-20:42
*/
 1 package com.atfu.java02.exer02;
 2 
 3 class Clerk{
 4     private int productCount = 0;
 5     //生产产品
 6     public synchronized void produceProductor(){
 7         if (productCount <20){
 8             productCount++;
 9             System.out.println(Thread.currentThread().getName()+ ":开始生产第"+productCount+"个产品");
10             notify();
11         }else {
12             try {
13                 wait();
14             } catch (InterruptedException e) {
15                 e.printStackTrace();
16             }
17         }
18     };
19 
20     //消费产品
21     public synchronized void consumerProductor() {
22         if (productCount>0){
23             System.out.println(Thread.currentThread().getName()+":开始消费第"+productCount+"个产品");
24             productCount--;
25             notify();
26         }else {
27             try {
28                 wait();
29             } catch (InterruptedException e) {
30                 e.printStackTrace();
31             }
32         }
33     }
34 
35 }
36 
37 class producer extends Thread{
38     private Clerk clerk;
39 
40     public producer(Clerk clerk) {
41         this.clerk = clerk;
42     }
43 
44     @Override
45     public void run() {
46         System.out.println(getName() + ":开始生产产品....");
47         while (true){
48             try {
49                 Thread.sleep(10);
50             } catch (InterruptedException e) {
51                 e.printStackTrace();
52             }
53             clerk.produceProductor();
54         }
55     }
56 }
57 
58 class Consumer extends Thread{
59     private Clerk clerk;
60 
61     public Consumer(Clerk clerk) {
62         this.clerk = clerk;
63     }
64 
65     @Override
66     public void run() {
67         while (true){
68             try {
69                 Thread.sleep(20);
70             } catch (InterruptedException e) {
71                 e.printStackTrace();
72             }
73             clerk.consumerProductor();
74         }
75     }
76 }
77 
78 public class ProductTest {
79     public static void main(String[] args) {
80         Clerk clerk = new Clerk();
81         producer p1 = new producer(clerk);
82         p1.setName("生产者1");
83         Consumer c1 = new Consumer(clerk);
84         c1.setName("消费者1");
85         Consumer c2 = new Consumer(clerk);
86         c2.setName("消费者2");
87         p1.start();
88         c1.start();
89         c2.start();
90     }
91 }

 

 
上一篇:线程的通信


下一篇:XPath、XSL练习笔记