gpt4 book ai didi

java - J2EE 环境 - 多线程 - 从不同的服务中并行获取数据

转载 作者:行者123 更新时间:2023-11-30 08:17:58 25 4
gpt4 key购买 nike

是否有比我在下面使用的更好的替代方案(设计/性能/内存优化):

问题陈述:在 J2EE 环境中,当请求到来时,我的 Controller 需要从三个不同的服务中获取数据(例如,第一个获取天气数据,第二个获取交通密度,最后一个获取当前访问我们的外星人数量)。如果一项服务需要 5 秒(最好的情况)来获取,那么以同步方式它们至少需要 15 秒。但 Controller 不应超过 6-7 秒。所以最终调用不同的线程。但可能存在服务花费超过 10 秒的情况(可能是最坏的情况)。

  1. So I thought of creating a thread wait, notify using an observable pattern with a small state maintaining. It was working, but not happy with the design.

  2. Then I found Java 'ForkJoinPool'. For each request controller creates a new 'ForkJoinPool' instance - now not creating it on each request. Created a custom class (say ForkService) extending RecursiveAction which has a List<RecursiveAction>. And ForkService's compute method has

@Override
protected void compute() {
for (RecursiveAction recursiveAction : actions) {
recursiveAction.fork(); // async calling of all other service's compute method which actually fetches the data from the relevant service.
}

mPool.shutdown();
}

目前正在使用它并且表现良好。想知道是否有更好的方法来做到这一点?

最佳答案

一个简单优雅的方法是使用固定的线程池和Guava的ListenableFuture您可以调用Futures.successfulAsList :

private MyResult getResult(MyRequest request) {
ExecutorService es = Executors.newFixedThreadPool(3);
ListeningExecutorService les = MoreExecutorslisteningDecorator(es);

ListenableFuture<?> lf1 = les.submit(getCallableForService1(request));
ListenableFuture<?> lf2 = les.submit(getCallableForService2(request));
ListenableFuture<?> lf3 = les.submit(getCallableForService3(request));
ListenableFuture<List<?>> lfs = Futures.successfulAsList(lf1, lf2, lf3);

// wait 7 sec for results
List<?> res = lfs.get(7, TimeUnit.SEONDS);

return extractRes(res);
}

您当然应该为 Callable 处理正确的类型。

关于java - J2EE 环境 - 多线程 - 从不同的服务中并行获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27868451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com