JUC学习之生产者和消费者

举报
多米诺的古牌 发表于 2021/07/27 23:21:51 2021/07/27
【摘要】 1.生产者和消费者的定义生产者和消费者即线程间的通信的问题的两种角色,生产者生产消费者需要的资源,消费者把资源做成产品(消耗掉)。只要是并发编程就必须加锁,因为多线程的情况下不加锁是不安全的,会导致数据错乱。2.生产者和消费者的实现等待(逻辑判断是否等待)==》业务(具体生产加减业务实现)==》通知(完成业务后等待,并且通知唤醒其他线程工作)3.虚假唤醒3.1 虚假唤醒的产生虚假唤醒是当一个...

1.生产者和消费者的定义

生产者和消费者即线程间的通信的问题的两种角色,生产者生产消费者需要的资源,消费者把资源做成产品(消耗掉)。

只要是并发编程就必须加锁,因为多线程的情况下不加锁是不安全的,会导致数据错乱。

2.生产者和消费者的实现

等待(逻辑判断是否等待)==》业务(具体生产加减业务实现)==》通知(完成业务后等待,并且通知唤醒其他线程工作)

3.虚假唤醒

3.1 虚假唤醒的产生

虚假唤醒是当一个条件满足时,很多的线程被唤醒了,但是只有一部分是有用的唤醒,其他都是无用的唤醒。

如果是两个线程,用if进行等待的逻辑判断一般不会出现问题,但是两个以上线程的时候用if进行等待的逻辑判断时,会出现虚假唤醒的情况。

比如执行生产者线程A的等待逻辑if判断一次后,生效进入wait等待的阶段,这个生产者线程线程A,只是阻塞了并没有结束,wait后会释放锁,唤醒其他线程,其中可能包括另外一个的生产者线程B,线程B也要进行逻辑判断和A一样会进入wait状态,当消费者线程C唤醒时,会将线程A和线程B同时唤醒,而此时线程A和线程B已经在if判断中,所以等于跳过了逻辑判断,直接进行后面的业务操作,就会出现数据异常状态。

3.2 如何解决虚假唤醒

使用while进行生产者和消费者的等待逻辑判断(尤其是两个以上线程),在一个线程判定为等待的时候,去唤醒其他线程,在这个唤醒的线程拿到锁后,会先进行判断,符合后才会进行业务代码。

解决线程中的虚假唤醒问题,主要在于阻塞到就绪的状态切换间加上判断,但是每次进行判断(while循环),会很浪费资源,cpu会一直占用着资源。

4.synchronized和lock实现生产者和消费者问题的区别

synchronized版是使用wait()方法进行阻塞线程(等待),notify()或者notifyAll()方法进行唤醒线程;

Lock锁版是使用Condition接口下的await()方法进行阻塞线程(等待),signal()或signalAll()方法进行唤醒线程,并且可以精准的唤醒线程(可以通过设置标记,来指定不同的监视器lock.newCondition())。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。