Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java同时调用多个Web服务_Java_Multithreading_Performance_Parallel Processing - Fatal编程技术网

使用Java同时调用多个Web服务

使用Java同时调用多个Web服务,java,multithreading,performance,parallel-processing,Java,Multithreading,Performance,Parallel Processing,我想在同一个方法中调用3个WebService,每个结果将在一个对象中设置,如下代码所示: public Dossie procuraPorCPF(String cpf) { Dossie dossie = new Dossie(); // first webservice call dossie.setCnh(detectaClientCnh.verificaCNH(cpf)); // second webservice call dossie.s

我想在同一个方法中调用3个WebService,每个结果将在一个对象中设置,如下代码所示:

public Dossie procuraPorCPF(String cpf) {

    Dossie dossie = new Dossie();

    // first webservice call
    dossie.setCnh(detectaClientCnh.verificaCNH(cpf));

    // second webservice call
    dossie.setFotoCnh(detectaClientCnhFoto.verificaFotoCNHPorCpf(cpf));

    // third webservice call
    dossie.setPm(consultaPMWService.getPMPorCPF(cpf).getProcuraPMPorCPFResult());

    return dossie;
}

在上面的这个例子中,我调用了3个不同的Web服务,它们每一个都需要大约5秒的时间,然后继续这个代码是不好的。我想知道同时调用3个Web服务的最佳方式是什么,以及如何使用此代码作为示例。我在这里搜索了一些文章甚至是答案,但我不知道怎么做。感谢您的耐心。

Java中的并发是通过Thread类处理的。线程构造函数接受一个Runnable参数和线程运行的代码。调用start方法时,JVM将创建新线程,并在Runnable的run方法中执行代码

由于Runnable只运行一个抽象方法,因此您可以使用。我对第一个调用使用了传统语法,对另外两个调用使用了lambda语法来演示这两种方法

public Dossie procuraPorCPF(String cpf) {
    Dossie dossie = new Dossie();
    Thread[] threads = new Thread[3];

    threads[0] = new Thread(new Runnable() {
        @Override
        public void run() {
            dossie.setCnh(detectaClientCnh.verificaCNH(cpf));
        }
    };
    threads[0].start();

    threads[1] = new Thread(() ->
        dossie.setFotoCnh(detectaClientCnhFoto.verificaFotoCNHPorCpf(cpf));
    threads[1].start();

    threads[2] = new Thread(() ->
        dossie.setPm(consultaPMWService.getPMPorCPF(cpf).getProcuraPMPorCPFResult());
    threads[2].start();

    try {
        threads[0].join();
        threads[1].join();
        threads[2].join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    return dossie;
}
join方法阻止程序执行,直到调用线程完成运行。通过将连接放置在方法的末尾,可以保证在返回之前所有3个请求都已完成。如果在返回之前这些请求是否已完成并不重要,那么您可以简单地删除连接,请求将在后台继续,而应用程序的其余部分将运行


对于更大的应用程序,Java还包括将为您管理线程创建的。由于您的应用程序在本地上下文中仅使用相同的3个可运行项,因此我认为上述解决方案更适合此答案,并且更具教育意义。

您可以使用ExecutorService提交Callable和call Future.get来检索结果,如下所示将Future更改为适当的返回值。如果可能的话,在应用程序启动时,您还应该考虑错误处理和在方法之外创建线程池

public Dossie procuraPorCPF(String cpf) {

    ExecutorService executor = Executors.newFixedThreadPool(3);

    Future<String> cnh = executor.submit(() -> detectaClientCnh.verificaCNH(cpf));
    Future<String> fotoCnh = executor.submit(() -> detectaClientCnhFoto.verificaFotoCNHPorCpf(cpf));
    Future<String> pm =
        executor.submit(() -> consultaPMWService.getPMPorCPF(cpf).getProcuraPMPorCPFResult());

    Dossie dossie = new Dossie();

    try {
      dossie.setCnh(cnh.get());
      dossie.setFotoCnh(fotoCnh.get());
      dossie.setPm(pm.get());
    } catch (InterruptedException | ExecutionException cause) {
      cause.printStackTrace();
    }
    executor.shutdown();
    return dossie;
  }
我在晚上开始写这个答案,然后留到第二天。早上给出了两个答案,其中一个被OP接受。将此答案留给希望看到完整设计和实现思想的人,而不是实际代码的人

设计: 由于web服务调用需要时间来响应,因此它们被异步调用,这意味着主线程与这些调用不同步

因此,它们的设计使您可以在单独的线程上进行单独的调用

对于您的情况,重要的Java元素包括:

; ; . 实施: 实现一个类,该类扩展实现可调用接口,并在调用方法中包含web服务的调用代码。 对所有三个web服务调用都这样做; 启动ExecutorService,它将为您执行此调用和结果收集; 当您必须进行调用时,创建三个调用的实例并将它们存储在ArrayList中; 使用在步骤2中创建的ExecutorService,调用在步骤3中创建的实例。 额外的一步:在我看来,这三个web服务调用需要以相同的顺序重复进行。我不懂这种语言——它不是英语。对于这样的代码,可以在实现步骤1中创建的类的顶部创建单独的orchestrator类


此orchestrator类可以扩展Thread类并进行三次web服务调用。现在,这个类可以异步运行,而不是进行三次web服务调用。保持代码模块化并抽象出复杂性。

您可以生成一个单独的工作线程来处理每个web服务调用。谢谢您的评论,我该怎么做?我已经读了很多文章,但是有很多不同的实现,我仍然不知道哪一个是最适合我的案例的解决方案。请看一看,让您开始思考这个问题。顺便说一句,我假设你没有使用Android。不,我没有,这是一个使用Spring Boot的web应用程序。谢谢,这段代码将解决我的问题。您能演示一下如何使用Java8的功能(如Future、FutureTask、Callable…)做同样的事情吗?似乎@Pankaj在这一点上击败了我一点背景:我写这个答案不仅仅是为了回答OP的问题,也是为了记录我为一个非常类似的问题所做的设计,我为一个带回家的面试任务解决了这个问题。你的回答很有用。在我发布的这个示例中,调用webservices的顺序无关紧要,但我将有一个新的实现,我需要等待一个特定调用的响应,然后再调用另一个webservices。