/**
* 经典例题:生产者/消费者问题:
* 生产者(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 }