1. 题目
-
生产者(Producer)将产品给店员(Clerk)
消费者(Customer)从店员(Clerk)处取走产品
店员最多拥有20件产品。当拥有20件产品时,如果生产者生产更多产品,店员会制止
店员如果没有产品,会叫消费者等一下。
2. 分析:
- 是否有多线程问题?
- 是的,生产者线程,消费者线程。
- 是否有共享数据?
- 有的。店员就是共享数据。
- 是否需要解决线程安全问题?
- 需要。通过三种同步机制。
- 是否涉及线程通信?
- 涉及。店员需要通知生产者暂定生产;通知消费者等一下。
3. 代码逻辑
- 将店员包装成一个类。其中包含对共享数据的操作和共享数据。
- 生产者包装成类,消费者包装成类。在类中使用单列模式对店员类进行调用。
4.代码实现
-
package test1; /** * @Author -..----.--...../-.--..-.-----.-/----.-.....-.--/-.----.-...----/-.-.-...-.--... * @Date 2021/10/23 13:02 */ class Clerk { // 店员 private int num; // 从生产者接受产品 public synchronized void producerProduct() { if (num < 20) { num++; notify(); System.out.println(Thread.currentThread().getName() + ":生产第" + num + "个产品"); } else { // 等待 try { wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + ":出现问题"); e.printStackTrace(); } } } // 给消费者产品 public synchronized void customerProduct() { if (num > 0) { System.out.println(Thread.currentThread().getName() + ":取走第" + num + "个产品"); num--; notify(); } else { // 等待 try { wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + ":出现问题"); e.printStackTrace(); } } } } class Producer implements Runnable { // 生产者 private Clerk clerk; // 单列模式 // 使用同一个对象 public Producer(Clerk clerk) { this.clerk = clerk; } @Override public void run() { System.out.println(Thread.currentThread().getName() + ":开始生产"); while (true) { try { Thread.sleep(500); } catch (InterruptedException e) { } clerk.producerProduct(); } } } class Customer implements Runnable { // 消费者 private Clerk clerk; // 单列模式 // 使用同一个对象 public Customer(Clerk clerk) { this.clerk = clerk; } @Override public void run() { System.out.println(Thread.currentThread().getName() + ":开始消费"); while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { } clerk.customerProduct(); } } } public class ProductTest { public static void main(String[] args) { Clerk clerk = new Clerk(); Producer producer = new Producer(clerk); Thread pt1 = new Thread(producer); pt1.setName("生产者1"); pt1.start(); Customer customer = new Customer(clerk); Thread ct1 = new Thread(customer); Thread ct2 = new Thread(customer); ct1.setName("消费者1"); ct2.setName("消费者2"); ct1.start(); ct2.start(); } }