iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java多线程:生产者与消费者案例
  • 323
分享到

Java多线程:生产者与消费者案例

2024-04-02 19:04:59 323人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录前言工具知识点设计思路具体步骤总结前言 想象一下生活中哪些是和线程沾边的?饭店炒菜就是一个很好的例子 首先客人要吃菜,前提是厨师要炒好,也就是说,厨师不炒好的话客人是没有饭菜的。

前言

想象一下生活中哪些是和线程沾边的?饭店炒菜就是一个很好的例子

首先客人要吃菜,前提是厨师要炒好,也就是说,厨师不炒好的话客人是没有饭菜的。这时候,厨师就是一个线程,客人拿菜就是另一个线程。

工具

jdk13,idea2019.1.4

知识点

Thread、Runnable、synchronized、面向对象知识(继承、封装、接口、方法重写)、条件判断以及线程的一些其他知识点

设计思路

首先要有两个线程,也就是说要两个类,分别是Producer(生产者)和Consumer(消费者)。

由于我们是模拟厨师与客人之间的互动,也就是说还需要一个类来封装信息:Message(类)。

然后,避免线程之间发生数据混乱的情况,肯定还需要使用synchronized来进行线程同步。

具体步骤

首先我们来一份没有用synchronized的代码,先看看效果:


public class Message {
    private String title;
    private String content;
    Message(){
    };
    public Message(String title, String content) {
        this.title = title;
        this.content = content;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}

class Producer implements Runnable{
    private Message msg=null;
    public Producer(Message msg) {
        this.msg = msg;
    }
    @Override
    public void run() {
        for (int i=0;i<=50;i++){
            if (i%2==0){
                this.msg.setTitle("喜欢夜雨吗?");
                try {
                    Thread.sleep(100);
                }catch (InterruptedException e){
                    System.out.println(e);
                }
                this.msg.setContent("是的呢!");
            }else {
                this.msg.setTitle("还不关注我吗?");
                try {
                    Thread.sleep(100);
                }catch (InterruptedException e){
                    System.out.println(e);
                }
                this.msg.setContent("好的呢!");
            }
        }
    }
}

class Consumer implements Runnable{
    private Message msg=null;
    public Consumer(Message msg) {
        this.msg = msg;
    }
    @Override
    public void run() {
        for (int i=0;i<=50;i++){
            try {
                Thread.sleep(100);
            }catch (InterruptedException e){
                System.out.println(e);
            }
            System.out.println(this.msg.getTitle()+"--->"+this.msg.getContent());
        }
    }
}
class TestDemo{
    public static void main(String[] args) {
        Message msg=new Message();
        new Thread(new Producer(msg)).start();
        new Thread(new Consumer(msg)).start();
    }
}

看看运行结果:

在这里插入图片描述

看仔细咯,发生了数据错乱啊,Title与Content没有一一对应欸。咋办?

能咋办,改代码呗。

发生数据混乱的原因完全是因为,生产者线程还没生产的时候,消费者就已经消费了(至于消费的啥我也不知道,我也不敢问啊)。所以造成了数据混乱,不过我们上面说了啊,要使用synchronized来让线程同步一下。但是又会出问题,我们接着往下看


class TestDemo{
    public static void main(String[] args) {
        Message msg=new Message();
        new Thread(new Producer(msg)).start();
        new Thread(new Consumer(msg)).start();
    }
}
class Message{
    private String title,content;
    public synchronized void set(String title,String content){
        this.title=title;
        this.content=content;
    }
    public synchronized void get(){
        try {
            Thread.sleep(1000);
        }catch (InterruptedException e){
            System.out.println(e);
        }
        System.out.println(this.title+"-->"+this.content);
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}
class Producer implements Runnable{
    private Message msg=null;
    Producer(Message msg){
        this.msg=msg;
    }
    @Override
    public void run() {
        for (int i=0;i<=50;i++){
            if (i%2==0){
                this.msg.set("喜欢夜雨吗?","是的呢!");
            }else {
                this.msg.set("还不关注吗?","好的呢!");
            }
        }
    }
}
class Consumer implements Runnable{
    private Message msg=null;
    Consumer(Message msg){
        this.msg=msg;
    }
    @Override
    public void run() {
        for (int i=0;i<=50;i++){
            this.msg.get();
        }
    }
}

我又重新封装了一些方法,然后运行的时候,wc,数据倒是不混乱了,但是呢,数据重复了一大堆。

在这里插入图片描述

为啥会出现这个问题呢?最后想了一下,会出现这种问题的,就是因为线程的执行顺序的问题。我们想要实现的效果是生产者线程执行了之后,让生产者线程等待,而后让消费者线程执行,等待消费者线程执行完成之后就又让生产者线程继续执行。后来我又查了查官方文档,发现Object类中专门有三个方法是与线程相关的:

方法 描述
public final void wait() throws InterruptedException 线程的等待
public final void notify() 唤醒第一个等待线程
public final void notifyAll()

当我看到这些方法的时候,心里愣了一下,这不就是我们想要的方法吗,用wait()方法来让生产者线程等待,然后运行消费者线程,等消费者线程执行完了之后又让生产者线程去执行。这其中我们用true和false来表示运行开始和运行暂停。

最后我们来看看完成品的代码:


class TestDemo{
    public static void main(String[] args) {
        Message msg=new Message();
        new Thread(new Producer(msg)).start();
        new Thread(new Consumer(msg)).start();
    }
}
class Message extends Exception{
    private String title,content;
    private boolean flag=true;
    // true表示正在生产,不要来取走,因为没由让消费者区走的
    // false表示可以取走,但是不能生产
    public synchronized void set(String title,String content){
        if (this.flag==false){
            try {
                super.wait();
            }catch (InterruptedException e){
                System.out.println(e);
            }
        }
        this.title=title;
        try {
            Thread.sleep(60);
        }catch (InterruptedException e){
            System.out.println(e);
        }
        this.content=content;
        this.flag=true; // 生产完成,修改标志位
        super.notify(); // 唤醒等待线程
    }
    public synchronized void get(){
        if (flag==true) {// 已经生产好了,等待取走
            try {
                super.wait();
            }catch (InterruptedException e){
                System.out.println(e);
            }
        }
        try {
            Thread.sleep(60);
        }catch (InterruptedException e){
            System.out.println(e);
        }
        System.out.println(this.title+"-->"+this.content);
        this.flag=true;
        super.notify();
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}
class Producer implements Runnable{
    private Message msg=null;
    Producer(Message msg){
        this.msg=msg;
    }
    @Override
    public void run() {
        for (int i=0;i<=50;i++){
            if (i%2==0){
                this.msg.set("喜欢夜雨吗?","是的呢!");
            }else {
                this.msg.set("还不关注吗?","好的呢!");
            }
        }
    }
}
class Consumer implements Runnable{
    private Message msg=null;
    Consumer(Message msg){
        this.msg=msg;
    }
    @Override
    public void run() {
        for (int i=0;i<=50;i++){
            this.msg.get();
        }
    }
}

运行结果我就不贴了,你们自己去测试一下吧…

总结

这个案例完美的呈现了线程以及面向对象知识的综合运用,具有很强的实际操作性

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Java多线程:生产者与消费者案例

本文链接: https://www.lsjlt.com/news/131270.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java多线程:生产者与消费者案例
    目录前言工具知识点设计思路具体步骤总结前言 想象一下生活中哪些是和线程沾边的?饭店炒菜就是一个很好的例子 首先客人要吃菜,前提是厨师要炒好,也就是说,厨师不炒好的话客人是没有饭菜的。...
    99+
    2024-04-02
  • Java多线程中的生产者与消费者案例讲解
    这篇文章主要讲解了“Java多线程中的生产者与消费者案例讲解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java多线程中的生产者与消费者案例讲解”吧!目录前言工具知识点设计思路具体步骤总结...
    99+
    2023-06-20
  • Java线程通信中关于生产者与消费者案例分析
    相关方法: wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。 notify():一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程被wait,就唤醒...
    99+
    2024-04-02
  • 生产者与消费者+Queue(线程安全)
    from queue import Queue from lxml import etree import requests from urllib import request from threading import Thread...
    99+
    2023-01-30
    生产者 线程 消费者
  • PHP实现生产者与消费者的案例
    这篇文章主要介绍PHP实现生产者与消费者的案例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!PHP中使用Kafka需要RdKafka扩展,而RdKafka依赖于librdkafka,所以这两个我们都需要安装,具体安装...
    99+
    2023-06-14
  • Java多线程之生产者消费者模式详解
    目录1.生产者消费者模型2.实现生产者消费者模型3.生产者消费者模型的作用是什么总结问题: 1.什么是阻塞队列?如何使用阻塞队列来实现生产者-消费者模型? 2. 生产者消费者模型的作...
    99+
    2024-04-02
  • Java多线程中消费者与生产者的关系是什么
    这篇文章将为大家详细讲解有关Java多线程中消费者与生产者的关系是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。  多线程:CPU中各种任务在交替执行过程中,被称为多线程处理。其中,每个任务的一次动态...
    99+
    2023-06-02
  • java 中多线程生产者消费者问题详细介绍
    java 中多线程生产者消费者问题前言:一般面试喜欢问些线程的问题,较基础的问题无非就是死锁,生产者消费者问题,线程同步等等,在前面的文章有写过死锁,这里就说下多生产多消费的问题了import java.util.concurrent.lo...
    99+
    2023-05-31
    java 多线程 ava
  • java中生产者消费者问题和代码案例
    目录应用场景分析解决方法管程法信号灯法总结应用场景 假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费 如果仓库中没有产品,则生产者将产品放入仓库...
    99+
    2024-04-02
  • Java多线程中消费者生产者模式怎么实现
    这篇文章主要讲解了“Java多线程中消费者生产者模式怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java多线程中消费者生产者模式怎么实现”吧!  //主类&nb...
    99+
    2023-06-17
  • 生产者消费者
    1、概念 所谓,生产者与消费者模型,本质上是把进程通信的问题分开考虑 生产者,只需要往队列里面丢东西(生产者不需要关心消费者) 消费者,只需要从队列里面拿东西(消费者也不需要关心生产者) 1 # 多线程实现生产者消费者模型 2 ...
    99+
    2023-01-30
    生产者 消费者
  • Java 生产者/消费者问题实例详解
    生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去...
    99+
    2023-05-31
    java 生产者消费者 ava
  • 爬虫——生产者消费者
    结构 生产者生成网址并放入队列 多个消费者从队列中取出网址 1 from queue import Queue 2 import time, threading, requests 3 4 url_base = 'ht...
    99+
    2023-01-30
    爬虫 生产者 消费者
  • JAVA项目中的生产者消费者如何利用多线程实现
    今天就跟大家聊聊有关JAVA项目中的生产者消费者如何利用多线程实现,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。JAVA多线程实现生产者消费者的实例详解Product.Javapac...
    99+
    2023-05-31
    java 多线程 ava
  • Java中的生产者/消费者模型
    一、什么是生产者/消费者模型 生产者-消费者模型(Producer-Consumer problem)是一个非常经典的多线程并发协作的模型。 比如某个模块负责生产数据,而另一个模块负责处理数据。产生数据的模块就形象地被称为生产者;而处理数据...
    99+
    2023-10-05
    java 多线程 wait notify notifyAll
  • Golang rabbitMQ生产者消费者实现示例
    目录消费者生产者消费者 package main import ( "fmt" "github.com/streadway/amqp" ) func failOnError(er...
    99+
    2024-04-02
  • java中生产者和消费者问题实例分析
    这篇“java中生产者和消费者问题实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“java中生产者和消费者问题实例分析...
    99+
    2023-06-29
  • kafka-3python生产者和消费者
    程序分为productor.py是发送消息端,consumer为消费消息端,启动的时候先启动product再启动consumer,毕竟只有发了消息,消费端才有消息可以消费,productor.py#!/usr/bin/env python2...
    99+
    2023-01-31
    生产者 消费者 kafka
  • java 中怎么实现生产者消费者
    今天就跟大家聊聊有关java 中怎么实现生产者消费者,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。生产者消费者图存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,...
    99+
    2023-06-17
  • Python中怎么利用多线程实现生产者消费者模式
    Python中怎么利用多线程实现生产者消费者模式,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。什么是生产者消费者模式在软件开发的过程中,经常碰到这样的场景:某些模块负责生产数据...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作