生产者和消费者模型是一种常用于描述多线程操作中生产者和消费者之间的关系。
想必大家都有过取餐排队的经历吧,特别是高峰期,买一份肯德基,经常要排好久的队才能到手,这是因为购买的人数太多,食物制作速度跟不上了。同理,如果食物制作的速度太快,但是买的人少,那工作人员就得等全部卖完才能再次制作。
这里就产生了消费者和生产者,如果消费者的速度大于生产者那么消费者就会经常处于等待状态;同理,如果生产者生产数据的速度很快,而消费者消费数据的速度很慢,那么生产者就必须等待消费者消费完数据才能继续生产数据;为了使生产者和消费者生产数据和消费数据达到平衡,那么就需要一个缓冲区用来存储生产者生产的数据,所有就引入了生产者-消费者模式。
有了这个队列,生产者就只需要关注生产,而不用管消费者的消费行为,更不用等待消费者线程执行完;消费者也只管消费,不用管生产者是怎么生产的,更不用等着生产者生产。
所以该模型实现了生产者和消费者之间的解藕和异步。
这种模型的使用场景非常广泛,例如:多线程编程、异步编程、消息队列等。生产者和消费者模型可以有效地控制数据流量,避免了生产者和消费者之间的资源竞争,提高了程序的效率和稳定性。
以下是一个使用 Java 实现生产者和消费者模型的示例代码
public class ProduceThread extends Thread{
private IKFC kfc;
public ProduceThread(String name, IKFC kfc){
super(name);
this.kfc = kfc;
}
@Override
public void run() {
while(true){
try{
kfc.produce(getName());
sleep(200);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
public class ConsumerThread extends Thread {
private IKFC kfc;
public ConsumerThread(String name, IKFC kfc) {
this.kfc = kfc;
}
@Override
public void run() {
while (true) {
try {
kfc.consume(getName());
sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class IKFCImpl implements IKFC {
private Queue<Food> queue = new LinkedBlockingQueue<>();
private final int MAX_SIZE = 10;
@Override
public synchronized void produce(String name) throws InterruptedException {
if(queue.size() >= MAX_SIZE){
System.out.println("生产者" + name + "] KFC生成达到上限,停止生成。。。。。。");
wait();
}else {
Food food = new Food("上校鸡鸡");
queue.add(food);
System.out.println("生成者" + name+ "生成一个:"+ food.getName()+"KFC有食物"+queue.size()+ "个");
// 唤醒等待的线程来消费
notifyAll();
}
}
@Override
public synchronized void consume(String name) throws InterruptedException {
if(queue.isEmpty()){
System.out.println("消费者" + name + "] KFC食物已经空,消费者停止消费。。。");
wait();
}else {
Food food = queue.poll();
System.out.println("消费者" + name+ "消费一个:"+ food.getName()+"KFC有食物"+queue.size()+ "个");
// 唤醒等待的线程来消费
notifyAll();
}
}
}
测试代码
public static void main(String[] args) {
IKFC kfc = new IKFCImpl();
Thread p1= new ProduceThread("A",kfc);
Thread p2= new ProduceThread("B",kfc);
Thread p3= new ProduceThread("C",kfc);
Thread c1 = new ConsumerThread("X",kfc);
Thread c2 = new ConsumerThread("Y",kfc);
Thread c3 = new ConsumerThread("T",kfc);
Thread c4 = new ConsumerThread("Z",kfc);
Thread c5 = new ConsumerThread("K",kfc);
p1.start();
p2.start();
p3.start();
c1.start();
c2.start();
c3.start();
c4.start();
c5.start();
}
感谢大家读到这里,后续还会有其他相关文章,欢迎继续阅读。