除了我在下面使用的方法以外,还有什么更好的选择(设计/性能/内存优化):
问题陈述:在J2EE环境中,当请求发出时,我的 Controller 需要从三种不同的服务中获取数据(例如,第一个获取天气数据,第二个获取交通密度,最后一个获取当前未访问我们的外星人)。并且,如果一项服务需要大约5秒钟(最好)来获取,那么以同步方式,它们将至少花费15秒。但是 Controller 的时间不应超过6-7秒。因此最终调用了不同的线程。但是在某些情况下,服务花费的时间可能会超过10秒(这可能是最坏的情况)。
@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
处理正确的类型。