【JAVA】经典的生产者-消费者

序言

闲来无事,记录学习历程,交个朋友。欢迎讨论碰撞,产生好的解决方案!!!👏👏👏

背景

记录一下生产者-消费者模型代码

代码

java 复制代码
package com.gyg.thread.demo2;
import java.util.LinkedList;
import java.util.Queue;

public class ProducerConsumerExample {
    public static void main(String[] args) {
        Buffer buffer = new Buffer(5); // 缓冲区大小为5

        // 创建生产者线程
        Thread producerThread = new Thread(new Producer(buffer));

        // 创建消费者线程
        Thread consumerThread = new Thread(new Consumer(buffer));

        // 启动线程
        producerThread.start();
        consumerThread.start();
    }
}

// 共享缓冲区
class Buffer {
    private Queue<Integer> queue = new LinkedList<>();
    private int capacity;

    public Buffer(int capacity) {
        this.capacity = capacity;
    }

    // 生产方法
    public synchronized void produce(int value) throws InterruptedException {
        // 如果缓冲区已满,生产者等待
        while (queue.size() == capacity) {
            System.out.println("缓冲区已满,生产者等待...");
            wait();
        }

        // 生产数据
        queue.offer(value);
        System.out.println("生产者生产: " + value + ",缓冲区大小: " + queue.size());

        // 通知消费者可以消费了
        notifyAll();
    }

    // 消费方法
    public synchronized int consume() throws InterruptedException {
        // 如果缓冲区为空,消费者等待
        while (queue.isEmpty()) {
            System.out.println("缓冲区为空,消费者等待...");
            wait();
        }

        // 消费数据
        int value = queue.poll();
        System.out.println("消费者消费: " + value + ",缓冲区大小: " + queue.size());

        // 通知生产者可以生产了
        notifyAll();

        return value;
    }
}

// 生产者
class Producer implements Runnable {
    private Buffer buffer;

    public Producer(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        try {
            int value = 0;
            while (true) {
                buffer.produce(value);
                value++;

                // 模拟生产时间
                Thread.sleep((int)(Math.random() * 1000));
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

// 消费者
class Consumer implements Runnable {
    private Buffer buffer;

    public Consumer(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        try {
            while (true) {
                buffer.consume();

                // 模拟消费时间
                Thread.sleep((int)(Math.random() * 1500));
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

关键点说明

共享缓冲区 (Buffer 类):

  • 使用 synchronized 关键字确保线程安全
  • 使用 wait() 使线程等待
  • 使用 notifyAll() 唤醒等待的线程

生产者线程 (Producer 类):

  • 不断生产数据并放入缓冲区
  • 当缓冲区满时自动等待
  • 生产后唤醒消费者

消费者线程 (Consumer 类):

  • 不断从缓冲区取出数据
  • 当缓冲区空时自动等待
  • 消费后唤醒生产者

注意事项:

  • 使用 while 循环检查条件而不是 if,防止虚假唤醒
  • 生产者和消费者都有随机的休眠时间,模拟实际处理时间
  • 缓冲区大小限制为5,当满时生产者会等待

尾声

如果解决有解决你的问题,点点赞,求个关注👍👍👍

安能催眉折腰事权贵,使我不得开心颜🤞🤞🤞,加油👏👏👏

相关推荐
个 人 练 习 生几秒前
C++ string 类模拟实现:从底层理解字符串(上)
开发语言·c++·经验分享·学习·程序人生
2601_966949659 分钟前
多市场量化策略的数据接口应该如何设计:从数据层架构到策略接入
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
坤坤子吖12 分钟前
C++智能指针:RAII、shared_ptr与内存泄漏
开发语言·c++·笔记·学习
奋斗的阿狸_198622 分钟前
ESP32-S3 + ES7210 四通道麦克风录音上传方案
c语言·开发语言·fpga开发
夜之眷属36 分钟前
Core dump 崩溃排查:JVM 宕机后,那份 core 文件怎么用 gdb 还原现场
java·运维·服务器·jvm
weixin1997010801637 分钟前
《1688图片空间API踩坑:img.upload 与 album.* 的防盗链与CDN缓存问题》(附Python源码)
开发语言·python·缓存
波加曼大王39 分钟前
# vLLM不要迷信PagedAttention神话,聊聊线上藏着的内部碎片陷阱
java·架构
SL_staff43 分钟前
目标健康度自检清单:开发者视角下的目标-计划-任务链路断点诊断
java·开源·github
for_ever_love__1 小时前
MySQL 高频面试题 30 问:索引、事务、锁、日志、主从与分库分表(MySQL 8.0 版)
java·数据库·spring boot·mysql·spring cloud·面试·总结
神仙别闹1 小时前
基于C++实现的贪吃蛇游戏平台
java·c++·游戏