生产者消费者模型

生产者和消费者模型是一种常用于描述多线程操作中生产者和消费者之间的关系。

想必大家都有过取餐排队的经历吧,特别是高峰期,买一份肯德基,经常要排好久的队才能到手,这是因为购买的人数太多,食物制作速度跟不上了。同理,如果食物制作的速度太快,但是买的人少,那工作人员就得等全部卖完才能再次制作。

这里就产生了消费者和生产者,如果消费者的速度大于生产者那么消费者就会经常处于等待状态;同理,如果生产者生产数据的速度很快,而消费者消费数据的速度很慢,那么生产者就必须等待消费者消费完数据才能继续生产数据;为了使生产者和消费者生产数据和消费数据达到平衡,那么就需要一个缓冲区用来存储生产者生产的数据,所有就引入了生产者-消费者模式。

在这里插入图片描述

有了这个队列,生产者就只需要关注生产,而不用管消费者的消费行为,更不用等待消费者线程执行完;消费者也只管消费,不用管生产者是怎么生产的,更不用等着生产者生产。
所以该模型实现了生产者和消费者之间的解藕和异步。

这种模型的使用场景非常广泛,例如:多线程编程、异步编程、消息队列等。生产者和消费者模型可以有效地控制数据流量,避免了生产者和消费者之间的资源竞争,提高了程序的效率和稳定性。

以下是一个使用 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();
    }

感谢大家读到这里,后续还会有其他相关文章,欢迎继续阅读。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值