使用 FixedThreadPool(s) 和队列的 Java 设计

标签 java multithreading concurrent.futures

我正在设计一个程序,该程序需要从数据存储区获取结果并将这些结果发布到另一个系统。我正在获取的数据由 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)?如果第一个队列中有很多作业,导致第二个队列在第一个队列为空之前无法启动,是否存在饥饿的危险?

fetcher 将通过网络联合与数据库对话,他们似乎更受 IO 的约束而不是 CPU 的约束。发帖人也将进行网络调用,但他们位于与我的代码运行所在的同一 VPC 中的云中,因此他们的距离相当近。

最佳答案

阻塞队列

这是一个很正常的模式。

如果您有两个不同的工作要做,请使用两个不同的线程池并使其大小可配置,以便您可以根据需要调整它们的大小/在部署服务器上测试不同的值。

通常使用具有有限大小(例如,任意示例为 1000 个元素)的阻塞队列(Java 5 及更高版本中内置的 BlockingQueue)。

阻塞队列是thread-safe ,所以第一个线程池中的所有内容都尽可能快地写入它,第二个线程池中的所有内容都尽可能快地读取。如果队列已满,写入只会阻塞,如果队列为空,读取只会阻塞 - 非常简单。

您可以调整线程数并重复运行以缩小每个池的最佳配置大小。

关于使用 FixedThreadPool(s) 和队列的 Java 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53822908/

相关文章:

java - Android 斐波那契基准/深度递归

c++ - 创建共享库时检测到段错误/glibc

c# - 为什么 performanceCounter 的 NextValue 调用会改变线程关联掩码

python - 是否可以在进程之间传递 Python Future 对象?

python - 如何在没有函数的情况下将 executor.map 应用于 for 循环?

multithreading - 在 FutureTask 中包装 Callable/Runnable 有什么好处?

java - Java中的集合可以容纳不同的子类吗?

java - 无法设置JFrame的Visible(false)

java - 从另一个 Java 应用程序停止/启动/重新启动 Java 应用程序

python - 为什么本地启动的线程不会在每次迭代结束时终止?