设计模式:如何优雅地手写生产者消费者模式
生产者消费者模式并不是GOF提出的23种设计模式之一,23种设计模式都是建立在面向对象的基础之上的,但其实面向过程的编程中也有很多高效的编程模式,生产者消费者模式便是其中之一,它是我们编程过程中最常用的一种设计模式。
在应用解耦、流量削峰等场景下常需要用到消息队列,生产者不断生产消息投递到队列里面,不必等待消费者消费;消费者从队列里面取消息进行处理,不需要找生产者要数据;这就是典型的生产者消费者模式,平衡了生产者消费者的处理能力,达到了解耦的目的。
当面试中被问“你了解那些设计模式”的时候,只回答一个单例模式未免显得有点不够专业,多了解一下效果可能会稍好一点。和单例模式对比,生产者消费者模式实现也比较简单,适合手写;对于其中的细节又可以再挖掘。
不多叨叨了,本文就自己实现一个阻塞队列,然后创建生产者和消费者,来实现一个简单的生产者消费者模式。
实现阻塞队列
- 生产者在队列未满时一直生产,满了则停止生产;
- 消费者在队列不为空的时候一直消费,空了则停止消费;
- 当消费者发现队列里面没有消息了通知生产者生产;
- 当生产者生产了消息通知消费者消费。
public class MyBlockingQueue {
private int maxSize;
private List<Long> queue;
public MyBlockingQueue(int maxSize) {
this.maxSize = maxSize;
this.queue = new ArrayList<>();
}
public synchronized void put() {
while (queue.size() == maxSize) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Long value = System.currentTimeMillis();
queue.add(value);
System.out.println("put:" + value);
notify();
}
public synchronized void take() {
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Long value = queue.get(0);
System.out.println("take:" + value);
queue.remove(0);
notify();
}
}
实现生产者
public class Producer implements Runnable {
private MyBlockingQueue queue;
public Producer(MyBlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
queue.put();
}
}
}
实现消费者
public class Consumer implements Runnable {
private MyBlockingQueue queue;
public Consumer(MyBlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
queue.take();
}
}
}
实现生产者消费者模型
public class Main {
public static void main(String[] args) throws InterruptedException {
MyBlockingQueue queue = new MyBlockingQueue(100);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
new Thread(producer).start();
Thread.sleep(10);
new Thread(consumer).start();
}
}
由于博主也是在攀登的路上,文中可能存在不当之处,欢迎各位多指教! 如果文章对您有用,那么请点个”推荐“,以资鼓励!
欢迎各位加我主页weixin,备注“博客园”,进入技术交流群,和我一起讨论和交流,共同进步!
分类:
设计模式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
2018-11-24 PyCharm出现TabError: inconsistent use of tabs and spaces in indentation最简单实用的解决办法
2018-11-24 Python编程从入门到实践笔记——异常和存储数据
2018-11-24 Python编程从入门到实践笔记——文件
2018-11-24 Python编程从入门到实践笔记——类
2018-11-24 Python编程从入门到实践笔记——函数
2018-11-24 Python编程从入门到实践笔记——用户输入和while循环
2018-11-24 Python编程从入门到实践笔记——字典