线程通信之传统的生产者消费者(await在while的原因)

本文介绍了线程通信中的传统生产者消费者问题,涉及老版的sync等待与解锁,新版的lock等待与signal,强调了在多线程环境下使用while循环判断的重要性。同时指出,await应置于while内以避免意外唤醒,并确保有相应的signal配合,避免线程无限期挂起。
摘要由CSDN通过智能技术生成

sync的等待(wait)与解锁(notify) 老版
lock的等待(wait)与解锁(singal) 新版
多线程的判断需要用while判断
在这里插入图片描述
await要放在while方法里面防止正在waiting被别的原因唤醒,放在while里面,会判断while里面的条件可能会重写挂起。

错误情况一:如果有两个生产者A和B,一个消费者C。当存储空间满了之后,生产者A和B都被wait,进入等待唤醒队列。当消费者C取走了一个数据后,如果调用了notifyAll(),注意,此处是调用notifyAll(),则生产者线程A和B都将被唤醒,如果此时A和B中的wait不在while循环中而是在if中,则A和B就不会再次判断是否符合执行条件,都将直接执行wait()之后的程序,那么如果A放入了一个数据至存储空间,则此时存储空间已经满了;但是B还是会继续往存储空间里放数据,错误便产生了。
错误情况二:如果有两个生产者A和B,一个消费者C。当存储空间满了之后,生产者A和B都被wait,进入等待唤醒队列。当消费者C取走了一个数据后,如果调用了notify(),则A和B中的一个将被唤醒,假设A被唤醒,则A向存储空间放入了一个数据,至此空间就满了。A执行了notify()之后,如果唤醒了B,那么B不会再次判断是否符合执行条件,将直接执行wait()之后的程序,这样就导致向已经满了数据存储区中再次放入数据。

注意:有await方法就要有signal方法或者signalAll方法,有wait方法就要有notify方法或者notifyAll方法。如果没有,则线程会一直挂起
线程通信的传统的生产者消费者

package com.example.demo.Test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Thread的传统的生产者和消费者
 *
 */
public class ThreadSignal {
   
    /**
     * 资源控制类
     * 添加   在0的基础上进行添加 1
     * 减少  在1的基础上进行减少
     */
    public static class SignalData{
   
        private ReentrantLock reentrantLock = new ReentrantLock();
        Condition condition = reentrantLock
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值