有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring引导在控制器内执行并行方法

我试图在我的控制器中执行一些并行方法,但是返回类型有一些问题

我有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) 个答案

  1. # 1 楼答案

    首先,更改可调用项的类型以避免强制转换:

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

    然后,您必须等待并行计算的结果。您不需要创建CompletableFuture,因为您可以直接从ExecutorService获取Future

        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;
    

    就这样

  2. # 2 楼答案

    我建议将completableFuture对象与SupplySync方法一起使用。 给你的方法如下:

    CompletableFuture<String> completableFuture
      = CompletableFuture.supplyAsync(() -> scrapperAutovit.searchAutovit);
    
    CompletableFuture<String> completableFuture1
      = CompletableFuture.supplyAsync(() -> scrapperOlx.searchOlxwith);
    
    CompletableFuture<String> completableFuture2
      = CompletableFuture.supplyAsync(() -> scrapperPubli24.searchPubli24);
    

    将用于检查您是否收到上述电话的回复

    像这样,您可以为scrapperOlx.searchOlxwithscrapperPubli24.searchPubli24completableFuture对象打开并行线程,等待执行完成该任务,然后合并所有数据,您可以进一步处理

    有关更多详细信息,请参阅下面的链接 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/

    这是理解未来的好例子 Multiple thenApply in a completableFuture