使用FixedThreadPool和队列的Java设计

Mar*_*ark 3 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)
Run Code Online (Sandbox Code Playgroud)

我从第一次调用中获得的唯一数据是docIds.我正在考虑将这些文档推送到队列中,并让一组工作者(取出者)将相关的调用返回到数据存储区以检索数据.

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
Run Code Online (Sandbox Code Playgroud)

第二组工作人员(海报)将从每个文档的第二个队列中读取并将结果发布到第二个系统.

我有一个问题,我应该创建1个FixedThreadPool(大小为X)还是两个FixedThreadPool(大小为X/2)?如果第一个队列中有很多作业,第二个队列在第一个队列为空之前就不会启动,是否存在饥饿的危险?

获取者将使网络coalls与数据库进行通信,他们似乎比CPU绑定更多的IO绑定.海报也会进行网络呼叫,但它们在我的代码运行的同一个VPC中的云中,因此它们将非常接近.

Joh*_*0te 5

阻止队列

这是一个很正常的模式.

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

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

阻塞队列是线程安全的,因此第一个线程池中的所有内容都尽可能快地写入,第二个线程池中的所有内容都尽可能快地读取.如果队列已满,则写入仅阻塞,如果队列为空,则读取只是阻塞 - 非常简单.

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