一句话导读
多线程实践中,最经典的就是生产者和消费者模式,多个生产者生产产品,由多个消费者消费产品。
目录
一、什么是生产者和消费者模式
生产者和消费者模式是一种经典的并发编程模式,用于解决生产者和消费者之间的生产和消费问题。在该模式中,生产者负责生产数据并将数据放入共享的缓冲区(或队列)中,而消费者则负责从缓冲区中取出数据并进行消费。生产者和消费者之间通过共享的缓冲区进行通信,但彼此之间并不直接进行通信。
二、模拟实现生产者消费者模式
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;
}
@Override
public 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;
}
@Override
public 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();
}
}