多线程-Java的经典实现-生产者和消费者模式
一句话导读
多线程实践中,最经典的就是生产者和消费者模式,多个生产者生产产品,由多个消费者消费产品。
目录
一句话导读
一、什么是生产者和消费者模式
二、模拟实现生产者消费者模式
1.场景描述
2.代码实现
需求分析:
1.面包对象:
2.工人对象:
3.消费者对象:
4.商店类:
5.主方法:
3.运行结果
一、什么是生产者和消费者模式
生产者和消费者模式是一种经典的并发编程模式,用于解决生产者和消费者之间的生产和消费问题。在该模式中,生产者负责生产数据并将数据放入共享的缓冲区(或队列)中,而消费者则负责从缓冲区中取出数据并进行消费。生产者和消费者之间通过共享的缓冲区进行通信,但彼此之间并不直接进行通信。
二、模拟实现生产者消费者模式
1.场景描述
模拟一个场景,多个生产即面包工人一直在生产面包,然后将面包放到商店里售卖,多个消费者即顾客到商店购买面包,有多少买多少。
2.代码实现
需求分析:
- 要有多个工人,并且会一直生产面包
- 要有商店放面包,并且能够接受面包的寄售和面包的售出
- 要有多个消费者,他们能够一直在商店购买面包
- 有个主方法,启动工厂生产面包,组织消费者去购买面包
通过以上分析,我们抽象出对应的对象:
1.面包对象:
有名称、类型等自己的特征
import lombok.AllArgsConstructor;
import lombok.Data;@Data
@AllArgsConstructor
public class Bread {private String name;
}
2.工人对象:
有名字等自己的属性,并有生产面包的能力,将面包放到商店货柜
import lombok.Data;import java.util.UUID;/*** 生产者对象*/
@Data
public class BreadProducer implements Runnable {// 生产者名称private final String producerName;public BreadProducer(String producerName) {this.producerName = producerName;}@Overridepublic void run() {while (true) {try {Bread bread = new Bread(Thread.currentThread().getName(), UUID.randomUUID().toString());//每个人生产的面包都放到商店货柜上寄售BreadStore.put(bread);System.out.println(Thread.currentThread().getName() + "生产了面包,现在库存有:" + BreadStore.BREAD_STORE.size());Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
3.消费者对象:
有编号、名称等自己的属性,并有购买面包的能力
/*** 消费者对象*/
public class BreadConsumer implements Runnable {private final String name;public BreadConsumer(String name) {this.name = name;}@Overridepublic void run() {while (true) {try {//去商店购买面包Bread bread = BreadStore.take();Thread.sleep(100);System.out.println(name + "购买了" + bread.getName() + ":" + bread.getId() + "面包");} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
4.商店类:
有个货柜,能寄售面包,能够卖面包
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;public class BreadStore {//要有货柜放面包,货柜只能放10个面包public static final BlockingQueue<Bread> BREAD_STORE = new LinkedBlockingQueue<>(10);//寄售面包public static void put(Bread bread) {try {BREAD_STORE.put(bread);} catch (InterruptedException e) {e.printStackTrace();}}//售出面包public static Bread take() {try {return BREAD_STORE.take();} catch (InterruptedException e) {e.printStackTrace();}return null;}
}
5.主方法:
设置3个工人生产,3个消费者消费
public class MainProcess {public static void main(String[] args) {//三个人一起开始生产面包Thread breadProducerZhangsan = new Thread(new BreadProducer("张三"));Thread breadProducerLisi = new Thread(new BreadProducer("李四"));Thread breadProducerWangwu = new Thread(new BreadProducer("王五"));breadProducerZhangsan.setName("breadProducerZhangsan");breadProducerLisi.setName("breadProducerLisi");breadProducerWangwu.setName("breadProducerWangwu");breadProducerZhangsan.start();breadProducerLisi.start();breadProducerWangwu.start();//三个个消费者去商店购买面包Thread breadConsumer1 = new Thread(new BreadConsumer("消费者1"));breadConsumer1.setName("breadConsumer1");breadConsumer1.start();Thread breadConsumer2 = new Thread(new BreadConsumer("消费者2"));breadConsumer2.setName("breadConsumer2");breadConsumer2.start();Thread breadConsumer3 = new Thread(new BreadConsumer("消费者3"));breadConsumer3.setName("breadConsumer3");breadConsumer3.start();}
}
3.运行结果
