生产者-消费者问题(计算机系统中的许多问题都可归结为此问题)描述如下:生产者与消费者可以通过一个环形缓冲池联系起来,环形缓冲池由几个大小相等的缓冲块组成,每个缓冲块容纳一个产品。每个生产者可不断地每次往缓冲池中送一个生产产品,而每个消费者则可不断地每次从缓冲池中取出一个产品。 编写程序模拟多个生产者和多个消费者共享缓冲池的生产和消费过程。 要求: 1. 设计信号量用于进行生产者-消费者、生产者-生产者、消费者-消费者之间的同步控制; 2. 创建多个(不少于5个)进程或者线程模拟生产者和消费者; 3. 缓冲池大小定义在10-20,缓冲块中的产品为数据; 4. 程序运行结果能实时显示缓冲池中生产和消费产品的过程,包括断点、推进时间、次序等,编程语言选用Java。
时间: 2024-02-13 12:04:59 浏览: 75
好的,这是一个经典的同步问题,需要使用信号量来进行同步控制。以下是一个Java实现的示例代码:
```java
import java.util.concurrent.Semaphore;
public class ProducerConsumer {
private static final int BUFFER_SIZE = 10;
private static final int NUM_PRODUCERS = 5;
private static final int NUM_CONSUMERS = 5;
private static Semaphore mutex = new Semaphore(1);
private static Semaphore empty = new Semaphore(BUFFER_SIZE);
private static Semaphore full = new Semaphore(0);
private static int[] buffer = new int[BUFFER_SIZE];
private static int in = 0;
private static int out = 0;
public static void main(String[] args) {
Thread[] producers = new Thread[NUM_PRODUCERS];
Thread[] consumers = new Thread[NUM_CONSUMERS];
for (int i = 0; i < NUM_PRODUCERS; i++) {
producers[i] = new Thread(new Producer(i));
producers[i].start();
}
for (int i = 0; i < NUM_CONSUMERS; i++) {
consumers[i] = new Thread(new Consumer(i));
consumers[i].start();
}
}
static class Producer implements Runnable {
private int id;
Producer(int id) {
this.id = id;
}
public void run() {
while (true) {
try {
Thread.sleep((long) (Math.random() * 1000));
empty.acquire();
mutex.acquire();
buffer[in] = id;
System.out.println("Producer " + id + " produced at " + in);
in = (in + 1) % BUFFER_SIZE;
mutex.release();
full.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Consumer implements Runnable {
private int id;
Consumer(int id) {
this.id = id;
}
public void run() {
while (true) {
try {
Thread.sleep((long) (Math.random() * 1000));
full.acquire();
mutex.acquire();
int data = buffer[out];
System.out.println("Consumer " + id + " consumed at " + out);
out = (out + 1) % BUFFER_SIZE;
mutex.release();
empty.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
```
在这个示例代码中,我们使用了三个信号量:mutex、empty和full。mutex用于保证对缓冲区的访问是互斥的,empty和full用于控制缓冲区中空闲和占用的缓冲块数量。当一个生产者要往缓冲区中放置一个数据时,它必须先获取empty信号量,表示空闲的缓冲块数量减少了一个;然后它必须获取mutex信号量,表示对缓冲区的访问是互斥的;接着它将数据放入缓冲区中,更新in指针,释放mutex信号量,表示这个缓冲块可以被其他生产者或消费者使用,最后它释放full信号量,表示占用的缓冲块数量增加了一个。当一个消费者要从缓冲区中取出一个数据时,它必须先获取full信号量,表示占用的缓冲块数量减少了一个;然后它必须获取mutex信号量,表示对缓冲区的访问是互斥的;接着它将数据从缓冲区中取出,更新out指针,释放mutex信号量,表示这个缓冲块可以被其他生产者或消费者使用,最后它释放empty信号量,表示空闲的缓冲块数量增加了一个。
阅读全文