Spring Boot выполняет параллельные методы внутри контроллера - PullRequest
0 голосов
/ 18 ноября 2018

Я пытаюсь выполнить несколько параллельных методов внутри моего контроллера, но у меня есть несколько проблем с типом возвращаемого значения.

У меня есть 4 метода, и каждый из этих методов возвращает список. Мне нужновыполнить эти методы параллельно, а затем получить каждый возвращенный список и поместить все эти списки в карту и вернуть эту карту из контроллера.Вот код:

Callable<List> callable1 = new Callable<List>()
           {
              @Override
              public List call() throws Exception
              {
                List<SearchResultAutovit> lista;
                lista = scrapperAutovit.searchAutovit(marcaId, modelId, pretDeLa, pretPanaLa, anFabrDeLa, anFabrPanaLa,
                        orasParam);
                 return lista;
              }
           };

           Callable<List> callable2 = new Callable<List>()
           {
              @Override
              public List call() throws Exception
              {
                  List<SearchResultOlx> listaOlx;
                String marcaOlx = marcaId.toLowerCase();
                String modelOlx = modelId.toLowerCase();
                String orasOlx = orasParam.toLowerCase();
                listaOlx = scrapperOlx.searchOlx(marcaOlx, modelOlx, pretDeLa, pretPanaLa, anFabrDeLa, anFabrPanaLa, orasOlx);
                 return listaOlx;
              }
           };

           Callable<List> callable3 = new Callable<List>()
           {
              @Override
              public List call() throws Exception
              {
                List<SearchResultPubli24> listaPubli24;
                String orasPubli24 = orasParam.toLowerCase();
                listaPubli24 = scrapperPubli24.searchPubli24(marcaId, modelId, orasPubli24, anFabrDeLa, anFabrPanaLa, pretDeLa, pretPanaLa);
                 return listaPubli24;
              }
           };

           Callable<List> callable4 = new Callable<List>()
           {
              @Override
              public List call() throws Exception
              {
                 List<SearchResultAutoUncle> listaAutoUncle;
                listaAutoUncle = scrapperAutoUncle.searchAutoUncle(marcaId, modelId, pretDeLa, pretPanaLa, anFabrDeLa, anFabrPanaLa, orasParam);
                 return listaAutoUncle;
              }
           };

           //add to a list
           List<Callable<List>> taskList = new ArrayList<Callable<List>>();
           taskList.add(callable1);
           taskList.add(callable2);
           taskList.add(callable3);
           taskList.add(callable4);

           ExecutorService executor = Executors.newFixedThreadPool(3);
           executor.invokeAll(taskList);

           Map<String,List<?>> listOfWebsites = new HashMap<>();
            listOfWebsites.put("listaAutovit", (List<?>) taskList.get(0));
            listOfWebsites.put("listaOlx", (List<?>) taskList.get(1));
            listOfWebsites.put("listaPubli24", (List<?>) taskList.get(2));
            listOfWebsites.put("listaAutoUncle", (List<?>) taskList.get(3));

        return listOfWebsites;

Я почти уверен, что я что-то не так делаю, потому что он выдает java.lang.ClassCastException: com.test.controller.HomeController$1 incompatible with java.util.List Я думаю, что проблема в карте под названием listOfWebsites, которая должна иметь возвращаемый тип вызываемых объектов.некоторые списки: (

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Сначала измените тип вызываемых объектов, чтобы избежать приведения:

    Callable<List<?>> callable1 = new Callable<List>(){...}

Затем вам нужно дождаться результатов параллельных вычислений.Вам не нужно создавать CompletableFuture с, потому что вы можете получить Future с непосредственно из ExecutorService:

    ExecutorService executor = Executors.newFixedThreadPool(3);
    Future<List<?>> future1 = executor.submit(callable1);
    Future<List<?>> future2 = executor.submit(callable2);
    Future<List<?>> future3 = executor.submit(callable3);
    Future<List<?>> future4 = executor.submit(callable4);

    Map<String,List<?>> listOfWebsites = new HashMap<>();
    listOfWebsites.put("listaAutovit", future1.get());
    listOfWebsites.put("listaOlx", future2.get());
    listOfWebsites.put("listaPubli24", future3.get());
    listOfWebsites.put("listaAutoUncle", future4.get());

    return listOfWebsites;

Вот и все.

0 голосов
/ 18 ноября 2018

Я бы предложил использовать завершенный объект будущего с методом supplyasync. Дать вам подход, как показано ниже:

CompletableFuture<String> completableFuture
  = CompletableFuture.supplyAsync(() -> scrapperAutovit.searchAutovit);

CompletableFuture<String> completableFuture1
  = CompletableFuture.supplyAsync(() -> scrapperOlx.searchOlxwith);

CompletableFuture<String> completableFuture2
  = CompletableFuture.supplyAsync(() -> scrapperPubli24.searchPubli24);

будет использоваться для проверки того, получили ли вы какой-либо ответ от вышеуказанного звонка или нет.

Таким образом, вы можете открыть параллельный поток для scrapperOlx.searchOlxwith и scrapperPubli24.searchPubli24 completetableFuture объекта и дождаться завершения выполнения задачи, а затем объединить все данные и продолжить обработку.

Для более подробной информации вы можете обратиться по ссылке ниже https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html https://dzone.com/articles/java-8-definitive-guide https://www.callicoder.com/java-8-completablefuture-tutorial/

Это хороший пример, чтобы понять завершаемое будущее Несколько затем Применить в завершаемом будущем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...