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

标签 java multithreading performance jakarta-ee design-patterns

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

问题陈述:在 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/

相关文章:

java - 如何更改音频文件的播放速率?

java - 我在哪里可以在 Ubuntu 机器上配置 Ant 1.8 的环境变量?

java - 如何在 JSP 中使用 JavaBeans 显示对象数组

c++ - 为什么 std::atomic_compare_exchange 更新期望值?

python - 是否可以在不引发异常的情况下迭代由另一个线程修改的字典?

c# - System.Threading.Tasks 不遵守启动规则?

java映射FileChannel实现

java - 从 GC 角度来看 Java 流的影响或通过 GC 处理短期对象

c# - 预定义列表容量

java - 如何在二维中使用字符串数组(String[][])并解析每个空间(指定元素点)中的数据?