生产者和消费者之间的线程通信

本文介绍了Java中生产者和消费者线程通信的原理和方法,通过`notify()`和`wait()`实现线程间的协作。在面包房类`BreadRoom`中,生产者`Produce`线程生产和消费者`Consume`线程消费通过同步方法进行控制,避免逻辑错误。当面包数量为0时,生产者通知消费者等待,消费者则通知生产者生产,确保了线程间的正确通信。
摘要由CSDN通过智能技术生成

线程通信:
生产者和消费者之间的关系前面几期已经跟大家讲了,不懂生产者和消费者之间的关系可以去看我之前的文章,今天主要讲他们之间的线程通信
在这里插入图片描述

线程通信就是线程之间可以交流,你告诉我要干什么,我告诉你要干什么,有两个很重要的方法notify()和wait(),顾名思义一个通知,一个等待

那么为什么要线程通信呢,既然他们两个是互不影响的,因为可能出现逻辑错误,比如说生产者在生产者的时候,此时消费者应该在等待,不能够去消费,比如说你去买面包,但是此时第一批已经卖完了,此时你是不可以消费的,所以说如果你还在消费说明是不是逻辑错误了,这个时候老板通知面包师父去做,在告诉你等一会就可以买了,这不就是正常的逻辑嘛,这个过程发生了对话这就是通信

notify:

notify()方法是object类下的,源码我们可以看到它是一个被final和natice修饰的方法,没有方法体,在多线程中它是用来唤醒一个等待的线程

在这里插入图片描述
wait

wait()方法也是object类下的一个方法,被final修饰,没有被native修饰,
还抛出了中断异常,方法体调用了他的一个重载方法,wait()方法一共有三个重载方法,它在多线程中通常是用来让一个线程进入等待状态

在这里插入图片描述接下来我们来写生产者与消费者通信代码

首先创建一个面包房类BreadRoom

package com.thread;


import java.util.Random;

/**
 * @author 邓亚非
 * 消费者来面包服买面包,如果面包服没有面包,面包房通知删除厂家去输出面包,然后通知消费者等待,等面包做好了
 * 面包做好了,面包房通知消费者消费,此时生产者等待,
 */
public class BreadRoom {

    Random random;
    private String name;//面包服名称
    private int count;

    public BreadRoom(String name) {
        this.name = name;
    }

    public synchronized void produce(BreadRoom breadRoom) {
        System.out.println(breadRoom == this);
        if (count == 0) {
            System.out.println("生产者开始生产给" + breadRoom.name);
//            一次生产1-到30个
            count = random.nextInt(29) + 1;
            System.out.println("生产了" + count + "个面包");
        }
//       此时通知消费者消费
        breadRoom.notify();
//        消费者消费的时候生产者等待
        try {
            breadRoom.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 消费者消费方法
     *
     * @param breadRoom
     */
    public synchronized void consume(BreadRoom breadRoom) {
        System.out.println(breadRoom == this);
        if (count == 0) {
//            面包数小于0,通知生产者生产
            breadRoom.notify();
//            生产者在生产消费者等待
            try {
                breadRoom.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
//            面包树大于0消费者可以消费
            System.out.println("消费者开始在" + breadRoom.name + "消费");
            int sum = random.nextInt(count) + 1;
            System.out.println("消费了" + sum + "个面包");
            count -= sum;
            System.out.println("面包还剩下" + count + "个");
        }
    }
}

创建生产者类Produce,需要依赖面包房类

package com.thread;

import com.sun.xml.internal.txw2.NamespaceResolver;

/**
 * @author 邓亚非
 * 生产者线程
 */
public class Produce extends Thread {

    private BreadRoom breadRoom;

    public Produce(BreadRoom breadRoom){
        this.breadRoom= breadRoom;
    }

    /**
     * 生产者线程体
     */
    @Override
    public void run() {
      while (true){
          breadRoom.produce(breadRoom);
          try {
              Thread.sleep(500);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
    }
}

创建消费者类Consume,也要依赖面包房类

package com.thread;

/**
 * @author 邓亚非
 */
public class Consume extends Thread{
 private BreadRoom breadRoom;

 public Consume(BreadRoom breadRoom){
     this.breadRoom=breadRoom;
 }

    /**
     * 消费者线程体
     */
    @Override
    public void run() {
        breadRoom.consume(breadRoom);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值