import java.util.Queue;
import java.util.LinkedList;
public class ProducerConsumerExample {
// 共享队列
private static final Queue<Integer> queue = new LinkedList<>();
private static final int LIMIT = 10;
// 生产者线程
static class Producer implements Runnable {
@Override
public void run() {
int value = 0;
while (true) {
synchronized (queue) {
while (queue.size() == LIMIT) {
try {
System.out.println("Queue is full, producer is waiting");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add(value++);
System.out.println("Produced: " + value);
queue.notifyAll();
}
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 消费者线程
static class Consumer implements Runnable {
@Override
public void run() {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
try {
System.out.println("Queue is empty, consumer is waiting");
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int value = queue.poll();
System.out.println("Consumed: " + value);
queue.notifyAll();
}
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread producerThread = new Thread(new Producer());
Thread consumerThread = new Thread(new Consumer());
producerThread.start();
consumerThread.start();
}
}
代码解释
-
共享队列:
-
使用
Queue
作为共享数据结构,存储生产者生成的数字。 -
LIMIT
定义了队列的最大容量。
-
-
生产者线程:
-
生产者线程在
run
方法中生成数字并将其添加到队列中。 -
如果队列已满,生产者线程会调用
wait()
方法等待,直到队列中有空间。 -
每次生产一个数字后,调用
notifyAll()
方法唤醒等待的消费者线程。
-
-
消费者线程:
-
消费者线程在
run
方法中从队列中取出数字并打印。 -
如果队列为空,消费者线程会调用
wait()
方法等待,直到队列中有数据。 -
每次消费一个数字后,调用
notifyAll()
方法唤醒等待的生产者线程。
-
-
同步机制:
-
使用
synchronized
块确保对共享队列的访问是线程安全的。 -
使用
wait()
和notifyAll()
方法实现线程间的同步。
-
注意事项
-
线程安全:使用
synchronized
块确保对共享队列的访问是线程安全的。 -
等待和通知:使用
wait()
和notifyAll()
方法实现线程间的同步。 -
随机延迟:在生产者和消费者线程中添加随机延迟,模拟实际的生产消费时间。