Java多线程生产者和消费者案例

1. 概述

在多线程编程中,生产者-消费者模式是一种常见的设计模式,用于解决多线程间的协作问题。生产者负责生成数据,而消费者负责处理数据。本文将指导你如何实现Java多线程生产者和消费者案例。

2. 流程图

flowchart TD
    start(开始)
    createBuffer(创建缓冲区)
    createProducer(创建生产者)
    createConsumer(创建消费者)
    start-->createBuffer
    createBuffer-->createProducer
    createBuffer-->createConsumer
    createProducer-->startProducing
    createConsumer-->startConsuming
    startProducing(开始生产)
    startConsuming(开始消费)
    startProducing-->produce(生产数据)
    startConsuming-->consume(消费数据)
    produce-->bufferPut(将数据放入缓冲区)
    consume-->bufferGet(从缓冲区获取数据)
    bufferPut-->bufferFull(缓冲区已满)
    bufferGet-->bufferEmpty(缓冲区已空)
    bufferFull-->wait(等待)
    bufferEmpty-->wait(等待)
    wait-->produce
    wait-->consume
    produce-->bufferEmpty
    consume-->bufferFull
    bufferEmpty-->stopProducing(停止生产)
    bufferFull-->stopConsuming(停止消费)
    stopProducing-->end(结束)
    stopConsuming-->end
    end(结束)

3. 步骤及代码示例

3.1 创建缓冲区

缓冲区用于存放生产者产生的数据,消费者从中获取数据。在Java中,我们可以使用阻塞队列来实现缓冲区,如java.util.concurrent.ArrayBlockingQueue

import java.util.concurrent.ArrayBlockingQueue;

public class Buffer {
    private ArrayBlockingQueue<Integer> buffer;
    private int maxSize;

    public Buffer(int maxSize) {
        this.maxSize = maxSize;
        this.buffer = new ArrayBlockingQueue<>(maxSize);
    }

    public void put(int data) throws InterruptedException {
        buffer.put(data);
    }

    public int get() throws InterruptedException {
        return buffer.take();
    }
}

3.2 创建生产者

生产者负责生成数据并将其放入缓冲区。在Java中,我们可以使用Thread类或Runnable接口来创建生产者线程。

public class Producer implements Runnable {
    private Buffer buffer;
    private int startValue;
    private int numItems;

    public Producer(Buffer buffer, int startValue, int numItems) {
        this.buffer = buffer;
        this.startValue = startValue;
        this.numItems = numItems;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < numItems; i++) {
                int data = startValue + i;
                System.out.println("Producing: " + data);
                buffer.put(data);
                Thread.sleep(100); // 模拟生产过程中的耗时操作
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

3.3 创建消费者

消费者负责从缓冲区中获取数据并进行处理。与生产者一样,我们也可以使用Thread类或Runnable接口来创建消费者线程。

public class Consumer implements Runnable {
    private Buffer buffer;
    private int numItems;

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

    @Override
    public void run() {
        try {
            for (int i = 0; i < numItems; i++) {
                int data = buffer.get();
                System.out.println("Consuming: " + data);
                Thread.sleep(100); // 模拟消费过程中的耗时操作
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

3.4 启动生产者和消费者线程

在主线程中创建缓冲区、生产者和消费者,并启动它们的线程。

public class Main {
    public static void main(String[] args) {
        Buffer buffer = new Buffer(10); // 创建缓冲区,大小为10
        Producer producer = new Producer(buffer, 0, 5); // 创建生产者,从0开始生产5个数据
        Consumer consumer = new Consumer