单核机器上的 CompletableFuture

Posted

技术标签:

【中文标题】单核机器上的 CompletableFuture【英文标题】:CompletableFuture on Single core machine 【发布时间】:2020-10-21 14:44:40 【问题描述】:

我有 Kafka 消费者生产应用程序,它使用一条消息并将其分成 3 个部分,并调用两个 Rest API 和一个 SOAP WS。目前这些是一个接一个地连续调用的,它们本质上是相互独立的,理想情况下应该是异步的。

Kafka 消费者也部署在具有 1 个核心的 Azure 小型 VM 上,链接相同 Azure VMs。

我打算使用CompletableFuturesupplyAsync(),但为此我可以选择下面提到的两个选项之一

    使用大小为 3 的自定义 Threadpool 或 使用forkjoin

既然我有一个单核机器,应该选择哪一个,为什么? CompletableFuture也适用于单核机吗?

【问题讨论】:

当然,你可以使用CompletableFuture; Java 的并发性与其他任何东西一样高级,并且从运行它的实际机器中抽象出来。这意味着,即使它实际上可以并行处理,JVM 也将自行安排其任务或仅按看起来合适的方式处理它 - 这可能是顺序的,但对于自定义线程或 forkjoin 池也是如此。跨度> 奇怪的是,CompletableFutureis specified as“All 异步 方法的行为没有显式 Executor 参数是使用 ForkJoinPool.commonPool() 执行的(除非它不支持至少两个并行级别,在这种情况下,会创建一个新线程来运行每个任务)。”因此,在单核机器上,您至少可以获得更多并行度从线程数的角度。因此建议使用显式执行器。一个 fork/join 池一个线程池。 @Holger 在单核机器中,fork join 普通池不是只有一个核吗(Runtime.getAvailableProcessors() 将返回 1),这意味着只有一个线程将被执行时间?如果是,那么使用 CompleteableFuture 没有任何意义。 正如文档所说,当公共池的并行度小于两个时,CompletableFuture 不使用公共池,而是为每个任务创建一个新线程。你可以从字面上理解它;然后它确实做到了new Thread(…),而无需使用任何执行程序服务。这就是为什么我建议在这种情况下使用具有合理配置的显式执行器。它可以是普通线程池,也可以是具有明确指定并行度的自定义 fork/join 池。 【参考方案1】:

您可以毫无问题地在单线程 cpu 上使用并发,但它只会对您的程序结构有益,而不是性能。

Kafka 为 CompletableFuture 1 类型 - KafkaFuture2 提供了它自己的 shim,您可能想改用它。

【讨论】:

以上是关于单核机器上的 CompletableFuture的主要内容,如果未能解决你的问题,请参考以下文章

在多线程应用程序表单上使用while循环锁定c#阻塞单核机器上的所有线程

为啥内存重新排序在单核/处理器机器上不是问题?

代码如何在同步的单核CPU上异步?

用于单核 Windows 7 机器的 Node.js 电子应用程序在文件 I/O 上很慢

单核CPU, 1G内存,也能做JVM调优吗?

单核中的多线程与异步编程