【发布时间】:2025-12-10 08:00:02
【问题描述】:
我有一个生产者-消费者场景,其中生产者的生产速度远快于消费者的消费速度。通常,解决方案是让生产者阻塞,因为生产者/消费者场景的运行速度与最慢的组件一样快。限制或阻止生产者不是一个好的解决方案,因为我们的应用程序提供了足够的时间让消费者稍后赶上。
下图描绘了我们的应用程序中的完整“阶段”与更常见的场景:
Our Application Common Scenario
2N +--------+--------+
|PPPPPPPP|oooooooo| P = Producer
|PPPPPPPP|oooooooo| C = Consumer
N +--------+--------+ N +--------+--------+--------+ o = Other Work
|CPCPCPCP|CCCCCCCC| |CPCPCPCP|CPCPCPCP|oooooooo| N = number of tasks
|CPCPCPCP|CCCCCCCC| |CPCPCPCP|CPCPCPCP|oooooooo|
------------------- ----------------------------
0 T/2 T 0 T/2 T 3T/2
这个想法是通过不抑制生产者来最大化吞吐量。
我们的任务操作的数据很容易序列化,因此我计划实施一个文件系统解决方案,用于溢出所有无法立即满足的任务。
我将 Java 的 ThreadPoolExecutor 与 BlockingQueue 一起使用,以确保我们不会耗尽内存。问题在于实现这样一个“分层”队列,其中可以在内存中排队的任务会立即完成,否则数据会在磁盘上排队。
我提出了两种可能的解决方案:
- 使用
LinkedBlockingQueue或ArrayBlockingQueue实现作为参考,从头开始实现BlockingQueue。这可能就像复制标准库中的实现并添加文件系统读/写一样简单。 - 继续使用标准的
BlockingQueue实现,实现一个单独的FilesystemQueue来存储我的数据,并使用一个或多个线程使文件出队,创建Runnables 并使用ThreadPoolExecutor将它们入队。
这两种方法都合理吗?是否有更好的方法?
【问题讨论】:
标签: java multithreading concurrency queue threadpool