【977、手写生产者消费者模型 】

120 阅读2分钟

以下是一个简单的Java生产者消费者模型的实现,使用wait()notify()来进行线程间的协调。请注意,这只是一个基本示例,实际使用中可能需要更复杂的同步机制和错误处理。

import java.util.LinkedList;

/**
 * 生产者消费者模型示例
 */
public class ProducerConsumerExample {

    public static void main(String[] args) {
        // 共享的缓冲区
        Buffer buffer = new Buffer(5);

        // 创建生产者和消费者线程
        Thread producerThread = new Thread(new Producer(buffer), "Producer");
        Thread consumerThread = new Thread(new Consumer(buffer), "Consumer");

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

/**
 * 缓冲区,用于生产者和消费者之间的数据交换
 */
class Buffer {
    private LinkedList<Integer> data;
    private int capacity;

    public Buffer(int capacity) {
        this.data = new LinkedList<>();
        this.capacity = capacity;
    }

    /**
     * 生产者将数据放入缓冲区
     */
    public synchronized void produce(int value) throws InterruptedException {
        // 如果缓冲区满了,等待消费者消费
        while (data.size() == capacity) {
            System.out.println("缓冲区已满,生产者等待");
            wait();
        }

        // 生产数据
        data.add(value);
        System.out.println("生产者生产: " + value);

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

    /**
     * 消费者从缓冲区取出数据
     */
    public synchronized int consume() throws InterruptedException {
        // 如果缓冲区为空,等待生产者生产
        while (data.isEmpty()) {
            System.out.println("缓冲区为空,消费者等待");
            wait();
        }

        // 消费数据
        int value = data.remove();
        System.out.println("消费者消费: " + value);

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

        return value;
    }
}

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

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

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            try {
                buffer.produce(i);
                // 模拟生产的时间
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

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

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

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            try {
                int value = buffer.consume();
                // 模拟消费的时间
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在这个例子中,Buffer类代表了共享的缓冲区,其中包含了produceconsume方法用于生产者和消费者之间的数据交换。ProducerConsumer分别是生产者和消费者的线程类。在主程序中,创建了一个Buffer实例,并启动了生产者和消费者线程。

请注意,为了避免虚假唤醒(spurious wake-ups),在使用wait()notify()时,通常在while循环中检查条件。这是因为在多线程环境中,线程可能会在没有明确通知的情况下醒来。