除了我在下面使用的方法以外,还有什么更好的选择(设计/性能/内存优化):

问题陈述:在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处理正确的类型。

10-07 19:14
查看更多