生产者消费者模型

一.生产者消费者模型的概念

生产者消费者模型多线程并发编程中的一种重要模式,用于解决生产者和消费者之间的协作问题。在这个模型中,生产者负责生成数据或者任务,然后将其交给消费者来处理,而消费者则负责处理这些数据或者任务

具体来说,生产者消费者模型通常涉及到一个共享的数据缓冲区(也称为队列),生产者向其中放入数据,而消费者从中取出数据进行处理。以下是该模型的基本概念:

  1. 生产者:负责生成数据或任务,并将其放入共享的数据缓冲区中。生产者的速度可能快于或者慢于消费者。

  2. 消费者:负责从共享的数据缓冲区中取出数据或任务,并进行处理。消费者可能以不同的速度处理数据,有些可能快速处理,有些可能慢速处理。

  3. 共享的数据缓冲区:生产者和消费者之间共享的数据存储区域。它可以是一个队列、缓冲区或者其他形式的数据结构。

  4. 协调机制:生产者和消费者之间需要一种机制来协调彼此的行为,例如当数据缓冲区为空时,消费者需要等待;当数据缓冲区满时,生产者需要等待。


二.生产者消费者模型的实现

1)阻塞队列

阻塞队列(Blocking Queue)是一种特殊类型的队列,它支持在队列为空时进行获取元素的线程阻塞等待,或者在队列已满时进行插入元素的线程阻塞等待。阻塞队列常用于生产者消费者模型中,可以帮助实现生产者和消费者之间的协调与同步。

代码实现:

public class BlockingQueue {

    //阻塞队列的长度
    private volatile int size;
    //存放数据的数组
    private int[] items=new int[1000];
    //队头
    private int head;
    //队尾
    private int tail;

    //put()方法放置生产者生产的元素
    public void put(int value) throws InterruptedException {
        //同一时间只能有一个线程放置,所以加锁
        synchronized (this){
            //如果队列满了,使当前线程等待,直到消费者消费元素后唤醒
            //建议为while而不是if, 否则 notifyAll 的时候, 该线程从 wait 中被唤醒
            //但是紧接着并未抢占到锁. 当锁被抢占的时候, 可能又已经队列满了
            //就只能继续等待
            while (size==items.length){
                wait();
            }
            //队列添加元素
            items[head]=value;
            head=(head+1)%items.length;
            size++;
            //添加后唤醒等待的线程
            notifyAll();
        }
    }

    //take()方法消耗消费者消费的元素
    public int take() throws InterruptedException {
        //用value存放要消耗的元素
        int value=0;
        synchronized (this){
            //如果队列为空,使当前线程等待,直到生产者消生产元素后唤醒
            while (size==0){
                wait();
            }
            //消耗元素
            value=items[tail];
            tail=(tail+1)%items.length;
            size--;
            //消费后唤醒等待的线程
            notifyAll();
        }
        return value;
    }
    
    //返回队列的长度
    public synchronized int size(){
        return size;
    }
}

2)模型实现

有了阻塞队列后,我们就可以简单的实现一个生产者消费者模型了

代码如下:

import java.util.Random;

public class Producer_Consumer {
    public static void main(String[] args) throws InterruptedException {
        //阻塞队列
        BlockingQueue blockingQueue=new BlockingQueue();

        //消费者线程
        Thread consumer=new Thread(()->{
            while (true){
                try {
                    //消费元素
                    System.out.println(blockingQueue.take());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //生产者线程
        Thread producer=new Thread(()->{
            Random random=new Random();
            while (true){
                try {
                    //生产元素
                    blockingQueue.put(random.nextInt(10000));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //启动线程
        consumer.start();
        producer.start();

        //等待线程执行完毕
        consumer.join();
        producer.join();

        //任务完成后的最后收尾
        System.out.println("生产者消费者执行完成");
    }
}

(代码实现时使用了lambda表达式,如对lambda不熟悉,可以参考lambda表达式-CSDN博客)

到这里,一个生产者消费者模型的简单流程和实现就介绍完了~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值