利用Java语言的进程同步机制,实现生产者-消费者例子。要求实现如下: 构造一个环形缓冲区类BoundedBuffer,容量为可以定义,假设每个单元内装有一个对象Image; 实现生产者Productor类,随机生成一个Image对象并延迟50ms(模拟实际运行环境),放入环形缓冲区,放入成功后打印提示; 实现消费者Consumer类,从环形缓冲区中取出一个Image,并输出其信息并延迟100ms(模拟实际运行环境); 构造主程序,生成一个容量为k的缓冲区对象,n个Productor对象,m个Consumer对象,并行访问环形缓冲区,通过改变k,n,m观察输出规律; 在完成以上内容的前提下,考虑利用条件变量技术改造环形缓冲区类,实现一个缓冲区管程;
时间: 2024-01-26 21:04:52 浏览: 115
经典线程同步问题(生产者&消费者)--Java实现.doc
好的,我可以为您提供一份Java代码示例,演示如何利用Java语言的进程同步机制实现生产者-消费者例子:
```java
import java.util.Random;
class Image {
private int id;
public Image(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
class BoundedBuffer {
private Image[] buffer;
private int head;
private int tail;
private int count;
private int capacity;
public BoundedBuffer(int capacity) {
this.buffer = new Image[capacity];
this.head = 0;
this.tail = 0;
this.count = 0;
this.capacity = capacity;
}
public synchronized void put(Image image) throws InterruptedException {
while (count == capacity) {
wait();
}
buffer[tail] = image;
tail = (tail + 1) % capacity;
count++;
notifyAll();
}
public synchronized Image take() throws InterruptedException {
while (count == 0) {
wait();
}
Image image = buffer[head];
head = (head + 1) % capacity;
count--;
notifyAll();
return image;
}
}
class Producer implements Runnable {
private BoundedBuffer buffer;
private int id;
private static int count = 0;
private static Random random = new Random();
public Producer(BoundedBuffer buffer) {
this.buffer = buffer;
this.id = ++count;
}
public void run() {
try {
while (true) {
Image image = new Image(random.nextInt(100));
buffer.put(image);
System.out.println("Producer " + id + " put image " + image.getId());
Thread.sleep(50);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Consumer implements Runnable {
private BoundedBuffer buffer;
private int id;
private static int count = 0;
public Consumer(BoundedBuffer buffer) {
this.buffer = buffer;
this.id = ++count;
}
public void run() {
try {
while (true) {
Image image = buffer.take();
System.out.println("Consumer " + id + " got image " + image.getId());
Thread.sleep(100);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public class Main {
public static void main(String[] args) {
int capacity = 5;
int numProducers = 3;
int numConsumers = 2;
BoundedBuffer buffer = new BoundedBuffer(capacity);
for (int i = 0; i < numProducers; i++) {
Thread producerThread = new Thread(new Producer(buffer));
producerThread.start();
}
for (int i = 0; i < numConsumers; i++) {
Thread consumerThread = new Thread(new Consumer(buffer));
consumerThread.start();
}
}
}
```
在这个示例中,我们首先定义了一个Image类来表示生产者生产和消费者消费的对象,然后定义了一个BoundedBuffer类来表示缓冲区,实现了put和take方法来实现生产者生产和消费者消费的逻辑。我们还定义了一个Producer类和一个Consumer类来实现生产者和消费者的具体实现,分别在run方法中不断地向缓冲区中放入Image对象和从缓冲区中取出Image对象,并打印相关的提示信息。最后,在主函数中创建了多个Producer和Consumer对象,并将它们放入不同的线程中并行执行。
接下来,我们将使用条件变量技术改造环形缓冲区类,实现一个缓冲区管程。在这个示例中,我们使用了Java中的Condition类来实现条件变量:
```java
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Image {
private int id;
public Image(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
class BoundedBuffer {
private Image[] buffer;
private int head;
private int tail;
private int count;
private int capacity;
private Lock lock;
private Condition notFull;
private Condition notEmpty;
public BoundedBuffer(int capacity) {
this.buffer = new Image[capacity];
this.head = 0;
this.tail = 0;
this.count = 0;
this.capacity = capacity;
this.lock = new ReentrantLock();
this.notFull = lock.newCondition();
this.notEmpty = lock.newCondition();
}
public void put(Image image) throws InterruptedException {
lock.lock();
try {
while (count == capacity) {
notFull.await();
}
buffer[tail] = image;
tail = (tail + 1) % capacity;
count++;
notEmpty.signalAll();
} finally {
lock.unlock();
}
}
public Image take() throws InterruptedException {
lock.lock();
try {
while (count == 0) {
notEmpty.await();
}
Image image = buffer[head];
head = (head + 1) % capacity;
count--;
notFull.signalAll();
return image;
} finally {
lock.unlock();
}
}
}
class Producer implements Runnable {
private BoundedBuffer buffer;
private int id;
private static int count = 0;
private static Random random = new Random();
public Producer(BoundedBuffer buffer) {
this.buffer = buffer;
this.id = ++count;
}
public void run() {
try {
while (true) {
Image image = new Image(random.nextInt(100));
buffer.put(image);
System.out.println("Producer " + id + " put image " + image.getId());
Thread.sleep(50);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Consumer implements Runnable {
private BoundedBuffer buffer;
private int id;
private static int count = 0;
public Consumer(BoundedBuffer buffer) {
this.buffer = buffer;
this.id = ++count;
}
public void run() {
try {
while (true) {
Image image = buffer.take();
System.out.println("Consumer " + id + " got image " + image.getId());
Thread.sleep(100);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public class Main {
public static void main(String[] args) {
int capacity = 5;
int numProducers = 3;
int numConsumers = 2;
BoundedBuffer buffer = new BoundedBuffer(capacity);
for (int i = 0; i < numProducers; i++) {
Thread producerThread = new Thread(new Producer(buffer));
producerThread.start();
}
for (int i = 0; i < numConsumers; i++) {
Thread consumerThread = new Thread(new Consumer(buffer));
consumerThread.start();
}
}
}
```
在这个示例中,我们将BoundedBuffer类中的锁和条件变量分别定义为Lock和Condition类型,并在put和take方法中使用它们来实现缓冲区的同步。在put方法中,当缓冲区已满时,线程会等待notFull条件变量,直到有消费者消费了一个Image对象并唤醒了notFull条件变量;在take方法中,当缓冲区为空时,线程会等待notEmpty条件变量,直到有生产者放入一个Image对象并唤醒了notEmpty条件变量。
阅读全文