生产者消费者问题java
时间: 2023-10-14 13:21:01 浏览: 38
生产者消费者问题是指一个固定缓冲区中,生产者将产品放入缓冲区,消费者从缓冲区取走产品,且缓冲区的大小有限。当缓冲区已经满时,生产者需要等待消费者取走产品后才能继续生产;当缓冲区已经空时,消费者需要等待生产者生产产品后才能继续消费。
下面是一个使用Java多线程和锁机制解决生产者消费者问题的示例代码:
```java
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumerExample {
public static void main(String[] args) {
Queue<Integer> buffer = new LinkedList<>();
int maxSize = 5;
Thread producer = new Producer(buffer, maxSize, "PRODUCER");
Thread consumer = new Consumer(buffer, maxSize, "CONSUMER");
producer.start();
consumer.start();
}
static class Producer extends Thread {
private Queue<Integer> buffer;
private int maxSize;
public Producer(Queue<Integer> buffer, int maxSize, String name) {
super(name);
this.buffer = buffer;
this.maxSize = maxSize;
}
@Override
public void run() {
while (true) {
synchronized (buffer) {
while (buffer.size() == maxSize) {
try {
System.out.println("Buffer is full, " + getName() + " is waiting...");
buffer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int num = (int) (Math.random() * 100);
buffer.add(num);
System.out.println("Produced " + num);
buffer.notifyAll();
}
}
}
}
static class Consumer extends Thread {
private Queue<Integer> buffer;
private int maxSize;
public Consumer(Queue<Integer> buffer, int maxSize, String name) {
super(name);
this.buffer = buffer;
this.maxSize = maxSize;
}
@Override
public void run() {
while (true) {
synchronized (buffer) {
while (buffer.isEmpty()) {
try {
System.out.println("Buffer is empty, " + getName() + " is waiting...");
buffer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int num = buffer.poll();
System.out.println("Consumed " + num);
buffer.notifyAll();
}
}
}
}
}
```
在这个例子中,我们使用了一个队列来模拟缓冲区,并创建了一个生产者线程和一个消费者线程。在生产者线程的run方法中,我们首先获得缓冲区的锁,然后检查缓冲区是否已满。如果缓冲区已满,生产者线程就会等待并释放锁,直到有消费者线程取走了一些产品来腾出空间。如果缓冲区还没有满,生产者线程会随机生成一个数字,将其加入到缓冲区,并打印出一个生产消息。最后,我们释放缓冲区的锁,并通知其他等待线程。
在消费者线程的run方法中,我们也首先获得缓冲区的锁,然后检查缓冲区是否为空。如果缓冲区为空,消费者线程就会等待并释放锁,直到有生产者线程将一些产品放入缓冲区。如果缓冲区不为空,消费者线程将从队列中取出一个数字,并打印出一个消费消息。最后,我们释放缓冲区的锁,并通知其他等待线程。
这个例子中使用了synchronized关键字来进行同步操作,以保证线程安全。同时,我们还使用了wait和notifyAll方法来实现线程间的协作,以避免一些不必要的CPU资源浪费。