进程通信(生成者-消费者)

本文详细介绍了Java中wait()和notify()方法在生产者消费者模型中的使用,展示了如何通过synchronized块和对象监视器实现线程间的同步和通信,确保生产者和消费者之间的有效协作。

在Java中,wait() 和 notify() 是用于线程间协作和同步的重要方法,它们都定义在 java.lang.Object 类中。这两个方法必须在 synchronized 同步块或方法中使用,因为它们依赖于对象的监视器(monitor),只有持有对象监视器的线程才能调用这些方法。

下面是一个简单的例子,展示如何在一个生产者消费者模型中使用 synchronizedwait() 和 notify() 方法:

import java.util.LinkedList;

public class ProducerConsumer {
    private final LinkedList<Integer> buffer = new LinkedList<>();
    private static final int BUFFER_SIZE = 10;
    
    public void produce() {
        while (true) {
            synchronized (buffer) {
                // 如果缓冲区已满,则生产者线程等待
                while (buffer.size() == BUFFER_SIZE) {
                    try {
                        System.out.println("Buffer is full, producer is waiting...");
                        buffer.wait(); // 生产者释放锁并进入等待状态
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }

                // 缓冲区未满,生产数据并放入缓冲区
                int data = generateData();
                buffer.add(data);
                System.out.println("Producer produced: " + data);

                // 唤醒可能存在的等待的消费者线程
                buffer.notify(); // 唤醒一个等待的线程
            }
        }
    }

    public void consume() {
        while (true) {
            synchronized (buffer) {
                // 如果缓冲区为空,则消费者线程等待
                while (buffer.isEmpty()) {
                    try {
                        System.out.println("Buffer is empty, consumer is waiting...");
                        buffer.wait(); // 消费者释放锁并进入等待状态
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }

                // 缓冲区非空,消费数据并移出缓冲区
                int data = buffer.removeFirst();
                System.out.println("Consumer consumed: " + data);

                // 唤醒可能存在的等待的生产者线程
                buffer.notify(); // 唤醒一个等待的线程
            }
        }
    }

    // 生成模拟数据的方法
    private int generateData() {
        return Math.abs(new Random().nextInt() % 100);
    }
}

// 使用示例:
public class Main {
    public static void main(String[] args) {
        ProducerConsumer pc = new ProducerConsumer();

        Thread producerThread = new Thread(pc::produce, "Producer");
        Thread consumerThread = new Thread(pc::consume, "Consumer");

        producerThread.start();
        consumerThread.start();
    }
}

在这个例子中:

  1. 我们创建了一个ProducerConsumer类,其中有一个可同步访问的缓冲区(LinkedList)。
  2. 生产者线程会在缓冲区满时调用 buffer.wait(),释放对象锁并进入等待状态,直到被其他线程唤醒。
  3. 消费者线程则在缓冲区空时调用 buffer.wait() 进入等待。
  4. 当生产者向缓冲区添加数据后,会调用 buffer.notify() 唤醒一个等待的消费者线程。
  5. 反过来,当消费者从缓冲区取出数据后,也会调用 buffer.notify() 唤醒可能等待的生产者线程。

这样,通过 synchronized 和 wait()notify() 方法的配合使用,实现了生产者和消费者线程之间的同步和通信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

semicolon_helloword

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值