生产者-消费者问题(计算机系统中的许多问题都可归结为此问题)描述如下:生产者与消费者可以通过一个环形缓冲池联系起来,环形缓冲池由几个大小相等的缓冲块组成,每个缓冲块容纳一个产品。每个生产者可不断地每次往缓冲池中送一个生产产品,而每个消费者则可不断地每次从缓冲池中取出一个产品。 编写程序模拟多个生产者和多个消费者共享缓冲池的生产和消费过程。 要求: 1. 设计信号量用于进行生产者-消费者、生产者-生产者、消费者-消费者之间的同步控制; 2. 创建多个(不少于5个)进程或者线程模拟生产者和消费者; 3. 缓冲池大小定义在10-20,缓冲块中的产品为数据; 4. 程序运行结果能实时显示缓冲池中生产和消费产品的过程,包括断点、推进时间、次序等,JAVA代码 并说明思路
时间: 2024-02-13 12:04:24 浏览: 59
好的,以下是一个简单的JAVA代码实现生产者-消费者问题,并说明思路:
```java
import java.util.concurrent.Semaphore;
class Buffer {
private int[] buffer;
private int bufferSize;
private int in = 0, out = 0, count = 0;
private Semaphore mutex, empty, full;
public Buffer(int bufferSize) {
this.bufferSize = bufferSize;
buffer = new int[bufferSize];
mutex = new Semaphore(1);
empty = new Semaphore(bufferSize);
full = new Semaphore(0);
}
public void put(int data, int id) throws InterruptedException {
empty.acquire();
mutex.acquire();
buffer[in] = data;
System.out.println("Producer " + id + " produced " + data);
in = (in + 1) % bufferSize;
count++;
mutex.release();
full.release();
}
public int get(int id) throws InterruptedException {
full.acquire();
mutex.acquire();
int data = buffer[out];
System.out.println("Consumer " + id + " consumed " + data);
out = (out + 1) % bufferSize;
count--;
mutex.release();
empty.release();
return data;
}
}
class Producer extends Thread {
private Buffer buffer;
private int id;
public Producer(Buffer buffer, int id) {
this.buffer = buffer;
this.id = id;
}
public void run() {
for (int i = 0; i < 100; i++) {
try {
buffer.put(i, id);
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer extends Thread {
private Buffer buffer;
private int id;
public Consumer(Buffer buffer, int id) {
this.buffer = buffer;
this.id = id;
}
public void run() {
for (int i = 0; i < 100; i++) {
try {
buffer.get(id);
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ProducerConsumer {
public static void main(String[] args) {
Buffer buffer = new Buffer(10);
Producer[] producers = new Producer[5];
Consumer[] consumers = new Consumer[5];
for (int i = 0; i < 5; i++) {
producers[i] = new Producer(buffer, i);
consumers[i] = new Consumer(buffer, i);
producers[i].start();
consumers[i].start();
}
}
}
```
思路:
1. 创建一个缓冲区类Buffer,实现了put和get方法来分别放入和取出数据,并定义了三个Semaphore信号量,用于进行同步控制。
2. 创建一个生产者Producer类和一个消费者Consumer类,分别调用Buffer类的put和get方法,其中id参数用于标识是哪个生产者或消费者产生的数据。
3. 在主函数中创建Buffer对象和多个生产者和消费者对象,并启动它们的线程。
4. 在Buffer类的put方法中,先使用empty信号量来判断缓冲区是否已满,如果已满则等待,否则继续执行。然后使用mutex信号量来进行互斥锁操作,将数据放入缓冲区,并更新in指针和count计数器。最后释放mutex信号量和full信号量。
5. 在Buffer类的get方法中,先使用full信号量来判断缓冲区是否为空,如果为空则等待,否则继续执行。然后使用mutex信号量来进行互斥锁操作,将数据从缓冲区取出,并更新out指针和count计数器。最后释放mutex信号量和empty信号量。
6. 在生产者和消费者的run方法中,循环调用Buffer类的put和get方法,并使用Math.random函数来随机等待一段时间,以便模拟实际生产和消费的过程。
7. 最终,在主函数中启动多个生产者和消费者线程,并运行程序,即可实时显示缓冲区中生产和消费产品的过程,包括断点、推进时间、次序等。
阅读全文