生产者-消费者问题(计算机系统中的许多问题都可归结为此问题)描述如下:生产者与消费者可以通过一个环形缓冲池联系起来,环形缓冲池由几个大小相等的缓冲块组成,每个缓冲块容纳一个产品。每个生产者可不断地每次往缓冲池中送一个生产产品,而每个消费者则可不断地每次从缓冲池中取出一个产品。 编写程序模拟多个生产者和多个消费者共享缓冲池的生产和消费过程。 要求: 1. 设计信号量用于进行生产者-消费者、生产者-生产者、消费者-消费者之间的同步控制; 2. 创建多个(不少于5个)进程或者线程模拟生产者和消费者; 3. 缓冲池大小定义在10-20,缓冲块中的产品为数据; 4. 程序运行结果能实时显示缓冲池中生产和消费产品的过程,包括断点、推进时间、次序等,编程语言可选用Java
时间: 2024-02-13 11:04:59 浏览: 23
好的,以下是使用 Java 实现的生产者-消费者问题的代码,使用信号量来进行多个进程或线程之间的同步和互斥。
```java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Semaphore;
public class ProducerConsumer {
// 缓冲池大小定义在10-20之间
private static final int BUFFER_SIZE = 15;
// 缓冲池
private static List<Integer> buffer = new ArrayList<>();
// 信号量
private static Semaphore mutex = new Semaphore(1);
private static Semaphore empty = new Semaphore(BUFFER_SIZE);
private static Semaphore full = new Semaphore(0);
// 生产者线程
private static class ProducerThread extends Thread {
public void run() {
while (true) {
try {
// 等待空缓冲块
empty.acquire();
// 获取互斥锁
mutex.acquire();
// 生产产品
int item = new Random().nextInt(100) + 1;
buffer.add(item);
System.out.println("Produced item " + item + ", buffer size = " + buffer.size());
// 释放互斥锁
mutex.release();
// 发送满信号量
full.release();
// 推迟一定时间,模拟生产过程
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 消费者线程
private static class ConsumerThread extends Thread {
public void run() {
while (true) {
try {
// 等待满缓冲块
full.acquire();
// 获取互斥锁
mutex.acquire();
// 消费产品
int item = buffer.remove(0);
System.out.println("Consumed item " + item + ", buffer size = " + buffer.size());
// 释放互斥锁
mutex.release();
// 发送空信号量
empty.release();
// 推迟一定时间,模拟消费过程
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
// 创建多个生产者和消费者线程
for (int i = 0; i < 5; i++) {
new ProducerThread().start();
}
for (int i = 0; i < 5; i++) {
new ConsumerThread().start();
}
}
}
```
在上面的代码中,我们使用了 Java 中的 Semaphore 类来实现信号量。每个线程都是 ProducerThread 或 ConsumerThread 类的实例,它们都是 Thread 类的子类,并重写了 run() 方法来实现线程的逻辑。
在 run() 方法中,生产者线程首先等待空缓冲块,然后获取互斥锁,生产一个随机数作为产品,并将其添加到缓冲池中。接着释放互斥锁,发送满信号量,并推迟一定时间,模拟生产过程。消费者线程的逻辑类似,只是等待满缓冲块,消费一个产品,并发送空信号量。
需要注意的是,在 Java 中,需要使用 try-catch 块来捕获 InterruptedException 异常,因为 acquire() 方法可能会抛出该异常。最后,我们创建了5个生产者和5个消费者线程,并启动它们。运行程序后,可以看到实时显示缓冲池中生产和消费产品的过程,包括断点、推进时间、次序等。
相关推荐
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)