生产者——消费者问题的模拟和实现Java
时间: 2025-06-22 11:39:13 浏览: 10
### Java 实现生产者-消费者问题
#### 使用 `BlockingQueue` 的简单实现方式
为了简化同步操作,在现代Java开发中通常推荐使用`java.util.concurrent.BlockingQueue`接口及其具体实现类,比如`ArrayBlockingQueue`。这种方式能够自动处理多线程环境下的阻塞和唤醒机制。
```java
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
class Producer implements Runnable {
private final BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> q) {
this.queue = q;
}
@Override
public void run() {
try {
int i = 0;
while (true) {
System.out.println("Producing " + i);
queue.put(i++); // 如果队列已满,则put会阻塞直到有空间可用
Thread.sleep((long)(Math.random() * 1000)); // 模拟随机时间间隔的产品创建过程
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Consumer implements Runnable {
private final BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> q) {
this.queue = q;
}
@Override
public void run() {
try {
while (true) {
Integer item = queue.take(); // 若无元素可取则take会一直等待直至有新元素加入
System.out.println("Consumed " + item);
Thread.sleep((long)(Math.random() * 2000)); // 模仿不同长度的时间消耗产品
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
```
这段代码展示了如何利用`BlockingQueue`来构建简单的生产者-消费者模型[^2]。这里的关键在于理解`queue.put()`和`queue.take()`这两个方法的工作原理——它们会在必要时自动挂起当前执行的线程,并在条件满足后恢复其运行状态。
#### 主程序启动多个生产和消费实例
下面是一个完整的例子,它初始化了一个固定大小的消息队列,并启动若干个生产者和消费者的线程:
```java
public class Main {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> sharedQueue = new ArrayBlockingQueue<>(2);
Thread producerThread1 = new Thread(new Producer(sharedQueue), "Producer-1");
Thread consumerThread1 = new Thread(new Consumer(sharedQueue), "Consumer-1");
producerThread1.start();
consumerThread1.start();
// 让主线程休眠一段时间以便观察子线程交互情况后再结束整个应用程序
Thread.sleep(5000L);
// 停止所有工作线程(实际应用中应设计更优雅的方式)
producerThread1.interrupt();
consumerThread1.interrupt();
}
}
```
此段代码片段说明了如何设置共享资源以及如何通过独立线程异步地向该资源共享数据或从中读取消息[^3]。
阅读全文
相关推荐




















