java - 使用 FixedThreadPool(s) 和队列的 Java 设计
问题描述
我正在设计一个程序,该程序需要从数据存储中获取结果并将这些结果发布到另一个系统。我正在获取的数据由 UUID 引用,并通过 UUID 链接到其他文档。我将发布很多文档(> 100K 文档),所以我想同时进行。我正在考虑以下设计:
从数据存储中获取文档列表。每个文件将具有:
docId (UUID)
docData (json doc)
type1 (UUID)
type1Data (json)
type2 (UUUID)
type2Data (json)
list<UUID> type3Ids
list of type3 data (json)
我从第一次通话中获得的唯一数据是 docId。我正在考虑将这些文档推送到队列中,并让一组工作人员(获取者)将相关调用返回到数据存储以检索数据。
retrieve the docData from datastore, fill in the type1, type2 and type3 UUIDS
do a batch get to retrieve all the type1, typ2 and type3 docs
Push the results into another queue for posting to other system
第二组工作人员(海报)将从第二个队列中读取每个文档并将结果发布到第二个系统。
我有一个问题,我应该创建 1 个 FixedThreadPool(size X) 还是两个 FixedThreadPool(size X/2)?如果第一个队列中有很多作业,以至于第二个队列在第一个队列为空之前不会启动,是否存在饥饿的危险?
提取器将制作网络煤来与数据库对话,它们似乎更多地受 IO 限制而不是 CPU 限制。张贴者也会进行网络调用,但它们在云中的同一 VPC 中,与我的代码运行的地方相同,因此它们会非常靠近。
解决方案
阻塞队列
这是一个很正常的模式。
如果您有两个不同的工作要做,请使用两个不同的线程池并使其大小可配置,以便您可以根据需要调整它们的大小/在部署服务器上测试不同的值。
通常使用BlockingQueue
具有有限大小(例如,对于任意示例为 1000 个元素)的阻塞队列(内置于 Java 5 及更高版本)。
阻塞队列是线程安全的,所以第一个线程池中的所有内容都尽可能快地写入,第二个线程池中的所有内容都尽可能快地读取。如果队列已满,则仅写入阻塞,如果队列为空,则仅读取阻塞-既好又简单。
您可以调整线程数并重复运行以缩小每个池的最佳配置大小。
推荐阅读
- javascript - 使用 Nodejs 和 ffmpeg 将 GIF 转换为 MP4,并将缓冲区作为输入
- python-3.x - python aiohttp响应时间慢
- java - 登录参数未使用 Volley 通过 REST 发布
- docker - 如何正确关闭这些 k8 容器?
- python - 在 QML 中显示 pandas 数据框
- python - 正则表达式用带有空白的http替换整个字符串
- java - 如何按递减顺序循环字符串?
- java - 如何通过 HTTP 服务器将 Java RMI 与动态类加载一起使用?
- assembly - 如何实现逻辑或 || 在easy68k中的if()条件下?
- python - 将另一个 Python 函数的名称作为参数的 Python 函数