1.生产者消费者问题(信号量) 参考教材中的生产者消费者算法,创建5个进程,其中两个进程为生产者进程,3个进程为消费者进程。一个生产者进程试图不断地在一个缓冲中写入大写字母,另一个生产者进程试图不断地在缓冲中写入小写字母。3个消费者不断地从缓冲中读取一个字符并输出。为了使得程序的输出易于看到结果,仿照的实例程序,分别在生产者和消费者进程的合适的位置加入一些随机睡眠时间。 可选的实验:在上面实验的基础上实现部分消费者有选择地消费某些产品。例如一个消费者只消费小写字符,一个消费者只消费大写字母,而另一个消费者则无选择地消费任何产品。消费者要消费的产品没有时,消费者进程被阻塞。注意缓冲的管理。这题用Java些代码
时间: 2024-03-14 16:46:24 浏览: 135
以下是使用Java的信号量实现的生产者消费者问题代码:
```java
import java.util.concurrent.Semaphore;
public class ProducerConsumer {
private static final int BUFFER_SIZE = 10; // 缓冲大小
private static final Semaphore mutex = new Semaphore(1); // 互斥信号量
private static final Semaphore empty = new Semaphore(BUFFER_SIZE); // 空闲信号量
private static final Semaphore full = new Semaphore(0); // 满信号量
private static final char[] buffer = new char[BUFFER_SIZE]; // 缓冲区
private static class Producer implements Runnable {
private final char product;
public Producer(char product) {
this.product = product;
}
@Override
public void run() {
while (true) {
try {
// 随机睡眠一段时间
Thread.sleep((long) (Math.random() * 1000));
// 等待空闲缓冲区
empty.acquire();
// 互斥访问缓冲区
mutex.acquire();
// 生产产品
for (int i = 0; i < BUFFER_SIZE; i++) {
if (buffer[i] == '\0') {
buffer[i] = product;
break;
}
}
System.out.println(Thread.currentThread().getName() + " produced " + product);
// 释放互斥信号量和满信号量
mutex.release();
full.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class Consumer implements Runnable {
private final char productType;
public Consumer(char productType) {
this.productType = productType;
}
@Override
public void run() {
while (true) {
try {
// 随机睡眠一段时间
Thread.sleep((long) (Math.random() * 1000));
// 等待满缓冲区
full.acquire();
// 互斥访问缓冲区
mutex.acquire();
// 消费产品
for (int i = 0; i < BUFFER_SIZE; i++) {
if (buffer[i] != '\0' && (productType == '\0' || buffer[i] == productType)) {
System.out.println(Thread.currentThread().getName() + " consumed " + buffer[i]);
buffer[i] = '\0';
break;
}
}
// 释放互斥信号量和空闲信号量
mutex.release();
empty.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread[] producers = new Thread[2];
Thread[] consumers = new Thread[3];
for (int i = 0; i < producers.length; i++) {
producers[i] = new Thread(new Producer(i % 2 == 0 ? 'A' : 'a'), "Producer " + (i + 1));
}
for (int i = 0; i < consumers.length; i++) {
if (i == 0) {
consumers[i] = new Thread(new Consumer('A'), "Consumer 1");
} else if (i == 1) {
consumers[i] = new Thread(new Consumer('a'), "Consumer 2");
} else {
consumers[i] = new Thread(new Consumer('\0'), "Consumer 3");
}
}
for (int i = 0; i < producers.length; i++) {
producers[i].start();
}
for (int i = 0; i < consumers.length; i++) {
consumers[i].start();
}
}
}
```
在上面的代码中,我们使用了Java的`Semaphore`类来实现信号量,其中`mutex`信号量用于互斥访问缓冲区,`empty`信号量用于表示空闲缓冲区的数量,`full`信号量用于表示满缓冲区的数量。
我们创建了两个生产者线程和三个消费者线程,其中一个生产者线程生产大写字母,另一个生产者线程生产小写字母,而消费者线程则根据需要消费相应的产品。在生产者和消费者的`run()`方法中,我们使用了`acquire()`和`release()`方法来获取和释放信号量。在生产者线程中,当缓冲区为空时,生产者线程会被阻塞,直到有消费者线程消费了一个产品释放了空闲信号量。同样地,在消费者线程中,当缓冲区已满且没有需要消费的产品时,消费者线程会被阻塞,直到有生产者线程生产一个产品释放了满信号量。
阅读全文