Java实现简易生产者消费者模型过程解析

 更新时间:2020年06月03日 09:30:58   作者:main(0)  
这篇文章主要介绍了Java实现简易生产者消费者模型过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

一、概述

一共两个线程,一个线程生产产品,一个线程消费产品,使用同步代码块方法,同步两个线程。当产品没有时,通知生产者生产,生产者生产后,通知消费者消费,并等待消费者消费完。

需要注意的是,有可能出现,停止生产产品后,消费者还没未来得及消费生产者生产的最后一个产品,就结束消费,导致最后一个产品没有被消费。

本例使用synchronize以及wait()、notify()实现简易版的线程者消费者模型。

二、测试用例

这里的产品用笔来演示,每只笔都有其编号code

一共有四个类:分别是生产者类,产品类,消费者类,测试类

产品

package test.exception.producer_consumer_model;

/*
假设为产品为笔
 */

public class Production {
  private String type = "";
  private String color = "";
  private long code = 0; // 产品编号
  private boolean isProduced = false; // 是否生产完成 初始状态为未生产状态
  private boolean isContinueProduce = true; // 是否停产该产品

  public void setContinueProduce(boolean continueProduce) {
    isContinueProduce = continueProduce;
  }

  public void setCode(long code) {
    this.code = code;
  }

  public Production(){
  }

  public boolean isContinueProduce() {
    return isContinueProduce;
  }

  public void setType(String type) {
    this.type = type;
  }

  public void setColor(String color) {
    this.color = color;
  }

  public void setProduced(boolean produced) {
    isProduced = produced;
  }

  public boolean isProduced() {
    return isProduced;
  }

  @Override
  public String toString() {
    return color + type + "-" + code;
  }
}

生产者

package test.exception.producer_consumer_model;

public class Producer implements Runnable {
  private final Production pen; // 产品

  public Producer(Production pen) {
    this.pen = pen;
  }

  // 生产
  public void produce() {
    long code = 0;
    while (this.pen.isContinueProduce()) {
      synchronized (this.pen) {
        if (this.pen.isProduced()) {
          try {
            this.pen.wait(); // 等待消费者消费
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
        // 开始生产
        this.pen.setType("铅笔");
        this.pen.setColor("蓝色");
        this.pen.setCode(code++);
        this.pen.setProduced(true);
        System.out.println(this.pen + " is produced");
        this.pen.notify();
      }
    }
    System.out.println("finish producing");
  }
  @Override
  public void run() {
    produce();
  }
}

消费者

package test.exception.producer_consumer_model;

public class Consumer implements Runnable {
  private final Production pen;

  public Consumer(Production pen) {
    this.pen = pen;
  }

  // 持续消费
  public void consumer() {
    while (this.pen.isContinueProduce()) {
      synchronized (this.pen) {
        if (!this.pen.isProduced()) {
          try {
            this.pen.wait(); // 等待生产者生产
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }

        System.out.println(this.pen + " is consumed"); // 使用
        this.pen.setProduced(false); // 使用完后更新状态
        this.pen.notify();
      }
    }
    // 确保停止生产后,能够使用最后生产的一支笔
    if (this.pen.isProduced()) {
      System.out.println(this.pen + " is consumed");
    }

    System.out.println("finish using");
  }

  @Override
  public void run() {
    consumer();
  }
}

主线程测试

package test.exception.producer_consumer_model;

public class Demo {
  public static void main(String[] args) throws InterruptedException {
    Production pen = new Production();
    Consumer consumer = new Consumer(pen);
    Producer producer = new Producer(pen);
    new Thread(producer).start(); // 开启生产者线程
    new Thread(consumer).start(); // 开启消费者线程

    Thread.sleep(10000);
    pen.setContinueProduce(false); // 10s后停止生产该类型的笔
  }
}

运行结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • idea中Stash与Unstash的使用及说明

    idea中Stash与Unstash的使用及说明

    这篇文章主要介绍了idea中Stash与Unstash的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • MyBatis中的配置文件详解

    MyBatis中的配置文件详解

    在 MyBatis 中,配置文件分为 全局配置文件(核心配置文件)和映射配置文件,本文给大家介绍MyBatis中的配置文件相关知识,感兴趣的朋友一起看看吧
    2023-10-10
  • 利用注解配置Spring容器的方法

    利用注解配置Spring容器的方法

    本篇文章主要介绍了利用注解配置Spring容器的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • PageHelper插件实现服务器端分页功能

    PageHelper插件实现服务器端分页功能

    这篇文章主要为大家详细介绍了PageHelper插件实现服务器端分页功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Java探索之string字符串的应用代码示例

    Java探索之string字符串的应用代码示例

    这篇文章主要介绍了Java探索之string字符串的应用代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 关于@Component注解下的类无法@Autowired问题

    关于@Component注解下的类无法@Autowired问题

    这篇文章主要介绍了关于@Component注解下的类无法@Autowired问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 使用Springboot整合GridFS实现文件操作

    使用Springboot整合GridFS实现文件操作

    这篇文章主要介绍了使用Springboot整合GridFS实现文件操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • java 获取request中的请求参数代码详解

    java 获取request中的请求参数代码详解

    这篇文章主要介绍了java 获取request中的请求参数的方法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-05-05
  • Spring基于常用AspectJ切点表达式使用介绍

    Spring基于常用AspectJ切点表达式使用介绍

    AspectJ是一个基于Java语言的AOP框架,使用AspectJ需要导入Spring AOP和AspectJ相关jar包,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • SpringBoot对Filter过滤器中的异常进行全局处理方案详解

    SpringBoot对Filter过滤器中的异常进行全局处理方案详解

    这篇文章主要介绍了SpringBoot对Filter过滤器中的异常进行全局处理,在SpringBoot中我们通过 @ControllerAdvice 注解和 @ExceptionHandler注解注册了全局异常处理器,需要的朋友可以参考下
    2023-09-09

最新评论