【Java】线程通信:生产者消费者问题
需求
解决生产者消费者的两种方法
- 管程法:
- 信号灯法
管程法
- 利用缓冲区
- 步骤
- 编写产品类Product
- 编写缓冲区Warehouse
- 生产者存商品方法
- 消费者取商品方法
- 编写生产者类Productor:只负责生产
- 编写消费者类Cunsomer:只负责消费
- 编写测试类:启动线程
- 代码
package com.cxl.demo08_communication; //管程法:利用缓冲区解决 //生产者、消费者、产品、缓冲区 public class Demo08_01_Monitor { public static void main(String[] args) { Warehouse warehouse = new Warehouse(); new Productor(warehouse).start(); new Consumer(warehouse).start(); } } class Productor extends Thread{ Warehouse warehouse; public Productor(Warehouse warehouse){ this.warehouse = warehouse; } //生产 @Override public void run() { for (int i = 1; i <= 100; i++) { try { warehouse.push(new Product(i)); System.out.println("生产者生产了第"+i+"个产品"); // Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer extends Thread { Warehouse warehouse; public Consumer (Warehouse warehouse) { this.warehouse = warehouse; } //消费 @Override public void run() { for (int i = 1; i <= 100; i++) { try { System.out.println("消费者购买了第"+warehouse.pop().id+"个产品"); // Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Product{ int id; public Product(int id) { this.id = id; } } class Warehouse{ Product[] products = new Product[10]; //仓库大小 int num = 0; //生产者存放商品 public synchronized void push(Product product) throws InterruptedException { //判断仓库是否已满 if (num == products.length) { //通知消费者,生产者等待 this.wait(); } products[num] = product; num++; //通知消费者取出 this.notifyAll(); } //消费者取出商品 public synchronized Product pop() throws InterruptedException { if (num == 0) { //等待消费者生产,消费者等待 this.wait(); } num--; Product product = products[num]; //通知生产者生产 this.notifyAll(); return product; } }
信号灯法
- 利用标志位
- 步骤
- 编写产品类Commodity
- 已有产品,等待消费
- 通知消费者开始消费
- 更新产品与信号
- 无产品,等待生产
- 通知生产者开始生产
- 更新信号
- 已有产品,等待消费
- 编写生产者类Producter:生产产品
- 编写消费者类Customer:消费产品
- 编写测试类:启动线程
- 编写产品类Commodity
- 代码
package com.cxl.demo08_communication; //信号灯法:利用标志位 public class Demo08_02_Signal { public static void main(String[] args) { Commodity commodity = new Commodity(); new Producter(commodity).start(); new Customer(commodity).start(); } } //生产者 class Producter extends Thread { Commodity commodity; public Producter(Commodity commodity) { this.commodity = commodity; } @Override public void run() { for (int i = 0; i < 10; i++) { try{ if (i % 3 == 0){ this.commodity.production("产品1"); }else { this.commodity.production("产品2"); } } catch (InterruptedException e) { e.printStackTrace(); } } } } //消费者 class Customer extends Thread { Commodity commodity; public Customer(Commodity commodity){ this.commodity = commodity; } @Override public void run() { try { for (int i = 0; i < 10; i++) { commodity.custorme(); } } catch (InterruptedException e) { e.printStackTrace(); } } } //产品 class Commodity{ String product; boolean flag = true; //启用生产 //生产者生产,消费者等待 public synchronized void production(String product) throws InterruptedException { if (!flag) { this.wait(); } System.out.println("生产者生产了商品:"+product); //通知消费者 this.notifyAll(); this.product = product; this.flag = !this.flag; } //消费者消费,生产那种等待 public synchronized void custorme() throws InterruptedException { if (flag) { this.wait(); } System.out.println("消费者消费了商品:"+product); //通知生产者生产 this.notifyAll(); this.flag = !this.flag; } }