我有一个List<HystrixCommand<?>>> commands
,执行这些命令并收集结果以便命令并行运行的最佳方法是什么?
我尝试过这样的事情:
List<Future<?>> futures = commands.stream()
.map(HystrixCommand::queue)
.collect(Collectors.toList());
List<?> results = futures.stream()
.map(Future::get)
.collect(Collectors.toList());
这会并行运行命令吗?
即调用HystrixCommand.queue()
时接下来是 Future.get()
在同一线程上,.get()
call 不会阻塞某些命令并延迟其他命令?
我问这个问题是因为我找不到任何相关文档。
<小时/>我还看过HystrixCollapser
,但这仍然需要在 createCommand
中创建并运行单个命令(如上)方法。
最佳答案
好吧,我已经调查了这一点并弄清楚了...通过创建一些简单的示例而不是调试生产代码...
<小时/>我的初始代码是正确的:
List<Request> requests = ...; // some expensive requests
List<HystrixCommand<?>>> commands = getCommands(requests);
List<Future<?>> futures = commands.stream()
.map(HystrixCommand::queue)
.collect(Collectors.toList());
List<?> results = futures.stream()
.map(Future::get)
.collect(Collectors.toList());
这些命令确实并行运行。
.get()
方法确实会阻塞,但由于所有命令都已排队(在任何 .get()
调用之前),因此它们都在运行(或排队等待运行)。
假设第二个命令比第一个命令更快完成。第一个 .get()
将阻塞,但当它最终返回时,第二个 .get()
调用将立即返回,因为第二个命令能够在第一个命令被阻止。 (假设核心尺寸 >=2。)
就HystrixCollapser
而言,我误解了API。 HystrixCollapser
用于将许多 HystrixCollapser
实例组合成一个 HystrixCommand
,而不是相反。因此,我必须修改代码以使用 HystrixCollapser
而不是 HystrixCommand
包装我的请求:
List<Request> requests = ...; // some expensive requests
List<HystrixCollapser<?>>> commands = getCommands(requests);
HystrixRequestContext context = HystrixRequestContext.initializeContext();
try {
List<Future<?>> futures = commands.stream()
.map(HystrixCollapser::queue)
.collect(Collectors.toList());
List<?> results = futures.stream()
.map(Future::get)
.collect(Collectors.toList());
} finally {
context.shutdown();
}
<小时/>
关于java - 并行运行多个 HystrixCommand 的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57422476/