生产者-消费者问题 Java 实现:多线程同步与互斥
生产者-消费者问题 Java 实现:多线程同步与互斥
生产者-消费者问题是一个经典的进程同步问题,用来描述生产者和消费者之间对共享资源的访问和协调。生产者负责生产数据并将其放入共享缓冲区,消费者则从缓冲区中获取数据进行消费。
问题描述:
假设系统中有一个有限大小的缓冲区,生产者和消费者共享该缓冲区。生产者可以将生产出的产品放入缓冲区,消费者可以从缓冲区中获取产品进行消费。为了保证程序的正确性,需要解决以下两个问题:
- 互斥: 同时只能有一个线程访问缓冲区,防止多个线程同时操作同一个缓冲区导致数据错误。
- 同步: 当缓冲区为空时,消费者线程需要等待生产者线程生产数据;当缓冲区已满时,生产者线程需要等待消费者线程消费数据。
Java 代码实现:
public class ProducerConsumer {
static int bufferSize = 5;
static int[] buffer = new int[bufferSize];
static int in = 0;
static int out = 0;
static int count = 0;
public static void main(String[] args) {
Thread producer = new Thread(new Producer());
Thread consumer = new Thread(new Consumer());
producer.start();
consumer.start();
}
static class Producer implements Runnable {
public void run() {
while (true) {
synchronized (buffer) {
while (count == bufferSize) { // 缓冲池满了,等待消费者消费
try {
buffer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffer[in] = (int) (Math.random() * 10);
System.out.println('Produced item: ' + buffer[in]);
in = (in + 1) % bufferSize;
count++;
buffer.notifyAll(); // 通知消费者
}
}
}
}
static class Consumer implements Runnable {
public void run() {
while (true) {
synchronized (buffer) {
while (count == 0) { // 缓冲池空了,等待生产者生产
try {
buffer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int item = buffer[out];
System.out.println('Consumed item: ' + item);
out = (out + 1) % bufferSize;
count--;
buffer.notifyAll(); // 通知生产者
}
}
}
}
}
代码说明:
- 缓冲区:
buffer数组表示共享缓冲区,bufferSize表示缓冲区大小。 - 索引:
in指向下一个生产的位置,out指向下一个消费的位置。 - 计数:
count表示缓冲区中当前的物品数量。 - 同步: 使用
synchronized块确保生产者和消费者对缓冲区的互斥访问。 - 等待: 使用
wait()方法使线程进入等待状态,直到其他线程使用notifyAll()方法唤醒它。 - 唤醒: 使用
notifyAll()方法唤醒所有等待该对象的线程。 - 生产:
Producer线程生成随机数,放入缓冲区,然后唤醒消费者线程。 - 消费:
Consumer线程从缓冲区中获取数据,然后唤醒生产者线程。
运行结果: 该程序会不断地生产和消费数据,并打印生产和消费的信息。
注意: 该代码示例只是一种简单的实现,实际应用中需要根据具体情况进行调整和优化。例如,可以使用 BlockingQueue 类来实现更加高效的缓冲区管理。
原文地址: https://www.cveoy.top/t/topic/nnPR 著作权归作者所有。请勿转载和采集!