【线程】——生产者消费者模型

本文介绍了Java中如何实现生产者消费者模型,通过一个阻塞队列作为中间容器,解耦生产者和消费者。当队列满时,生产者线程等待;队列空时,消费者线程等待。详细讲解了`wait()`、`notify()`方法的使用,以及在同步代码块中的应用。
摘要由CSDN通过智能技术生成

多线程经典示例——生产者消费者模型

所谓的生产者消费者模型,是通过一个容器来解决生产者和消费者的强耦合问题。通俗的讲,就是生产者在不断的生产,消费者也在不断的消费,可是消费者消费的产品是生产者生产的,这就必然存在一个中间容器,我们可以把这个容器想象成是一个货架,当货架空的时候,生产者要生产产品,此时消费者在等待生产者往货架上生产产品,而当货架满的时候,消费者可以从货架上拿走商品,生产者此时等待货架的空位,这样不断的循环。那么在这个过程中,生产者和消费者是不直接接触的,所谓的‘货架’其实就是一个阻塞队列,生产者生产的产品不直接给消费者消费,而是仍给阻塞队列,这个阻塞队列就是来解决生产者消费者的强耦合的。就是生产者消费者模型。
在这里插入图片描述

– 生产者(生产数据)如:擀饺子皮
– 消费者(消费数据)如:包饺子

那么这么模型的作用是什么呢?

系统解耦,将系统模块化,每个角色负责自己的功能(比如现在很多公司分为前端和后端,前端负责页面处理,后端负责逻辑处理)

生产者和消费者都需要一个中间介质——阻塞队列

那么阻塞队列有哪些特征呢?
  • 当生产者生产的比较快的收,队列已经放满了,生产者就会阻塞等待消费者消息之后来唤醒消费者继续生产
  • 当消费者消费的比较快的时候,队列里面没有数据了,他就可以阻塞等待生产者生产了数据之后唤醒它继续消费
案例实现

实现一个队列,队列的实现方式有两种,链表和数组都可以,那么这里就用数组来实现,其中实现两个方法,一个put()添加元素操作,和pop()弹出队顶元素操作
put()操作 —— 生产者
pop()操作——消费者
1.当生产者put()操作生产的太快的时候,就让其等待,等到消费者pop()弹出元素空出空间来之后唤醒put()操作
2.当消费者pop()操作太快的时候,就让其等待,等到生产者生产出一条数据的时候,唤醒put()操作

注意wait()方法的使用

1.wait()是Object里面的方法,而不是Thread里面的,这一点很容易搞错。它的作用是将当前线程置于预执行队列,并在wait()所在的代码处停止,等待唤醒通知。
2.wait()只能在同步代码块或者同步方法中执行,如果调用wait()方法,而没有持有适当的锁,就会抛出异常。wait()方法调用后会释放出锁,线程与其他线程竞争重新获取锁。

notify()方法的使用

1.notify()方法也是要在同步代码块或者同步方法中调用的,它的作用是使停止的线程继续执行,调用notify()方法后,会通知那些等待当前线程对象锁的线程,并使它们重新获取该线程的对象锁,如果等待线程比较多的时候,则有线程规划器随机挑选出一个呈wait状态的线程。
2.notify()调用之后不会立即释放锁,而是当执行notify()的线程执行完成,即退出同步代码块或同步方法时,才会释放对象锁。

代码实现


import java.util.concurrent.TimeUnit;

//使用循环数组实现生产者消费者模型
public class ThreadDemo18 {
   
    //Java里面的数组需要初始化容量,因为目前不知道,使用根据用户输入来决定
    int[] items = null;
    int first;//队首元素下标——出列的时候会用到
    int last;//队尾元素下标——入队的时候会用到
    int size;//实际存储容量

    //初始化,传一个容量参数
    public 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值