4

我们有一个 stipes (java) 网络应用程序,它需要从一个方法进行大约 15 次不同的网络服务调用。例如: ...

    public Resolution userProfile()
    {
        serviceOneCall();
        serviceTwoCall();
        serviceThreeCall();
        serviceFourCall();
        ....
        serviceTenCall();

        return new RedirectResolution("profiel.jsp");
    }

所有这些都可以并行调用,并且不相互依赖。大多数所有这些调用都在做的一件事是将数据放入会话中,并且一两个可能会将数据放入会话中的同一个对象中,因此线程安全可能是一个问题。

任何人都可以提出一个同时调用所有这些的好方法吗?

4

3 回答 3

5

使用ExecutorService带有线程池的 an 来为您需要调用的每个 WS 提交Callables,并在有可能并发修改时在更新的对象上进行同步。

您可能希望使用Guava 的并发扩展来更轻松地管理Futures,例如使用Futures.allAsList()它将 a 转换List<Future<T>>为 a Future<List<T>>,因此您只需get()等待所有答案即可。

于 2012-09-13T20:14:53.077 回答
5

并行执行这项工作的所有解决方案都将涉及产生新线程或将作业提交到线程池以发生远程网络调用。

避免线程安全问题的一个好方法是使用一个executorService并提交子类Callable<T>(到submit(Callable)orinvokeAll(Collection<Callable>)方法)并让 Callables 返回响应值。这样,您的初始方法可以简单地处理每个调用的返回值,并选择在会话中设置响应或更新其他对象,而不是在另一个线程中进行这项工作。

所以基本算法:

  1. 将这些调用中的每一个提交到Callable<T>子类中的 executorService
  2. 收集Future<T>你从 executorService 取回的 s
  3. 调用Future.get()每个阻塞,直到你有响应,然后处理响应,但是你希望回到主线程
于 2012-09-13T20:16:52.047 回答
-2
for (i = 0; i <= numOfServiceCalls; i++) {
    new Thread(new Runnable() {
        switch(i) {
            case 1 : serviceOneCall();
                     break();
            case 2 : serviceTwoCall();
                     break();
            // Keep going with as many cases as you have.
        }
    });
}
于 2012-09-13T19:56:55.340 回答