是否有比我下面使用的更好的替代方案(设计/性能/内存优化):
问题陈述:在 J2EE 环境中,当请求到来时,我的 Controller 需要从三个不同的服务获取数据(例如,第一个获取天气数据,第二个获取交通密度,最后一个获取当前访问我们的外星人数量)。如果一项服务需要 5 秒(最好的情况)来获取,那么以同步方式,它们将至少需要 15 秒。但 Controller 不应超过 6-7 秒。所以最终在不同的线程中调用。但在某些情况下,服务可能需要超过 10 秒(可能是最坏的情况)。
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.
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 (sayForkService
) extendingRecursiveAction
which has aList<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/