Spring Boot同时执行2种方法

时间:2018-09-26 19:08:40

标签: java spring multithreading spring-boot

我在发布请求时让spring boot控制器执行了两个返回2个列表的方法,并将这2个列表发送到视图页面。 这两种方法每个都需要15秒才能运行,因此控制器将这些列表发送到页面需要30-40秒。我如何能够同时执行这些方法并减少时间呢?但它什么也没做:(

@RequestMapping(path = "search", method = RequestMethod.POST)
    public String searchPage(@ModelAttribute("specification") Specification specification, Model model) throws InterruptedException {

        List<SearchResult1> list1;
        List<SearchResult2> lista2;

        list1 = service1.search(params);

        list2 = service2.search(params);

        model.addAttribute("list1", list1);

        model.addAttribute("list2", list2);


        return "home";
    }

2 个答案:

答案 0 :(得分:0)

如果使用线程执行程序池或search使@Async方法异步,则可以立即调用它们,并在完成后收集结果。

请记住,您必须为此使用Future

所以这样的话

@Async
public Future<List<Whatever>> search(whatever here){
      resultList=whateverYouDoThere();
      return new AsyncResult<Whatever>(resultList);   
}

在c的服务和调用中:

   List<Whatever> completeList=new ArrayList():
   Future<Whatever> fut1=service1.search(...);
   Future<Whateva> fut2=service2.search(...);
   completeList.addAll(fut1.get());
   completeList.addAll(fut2.get();
    //here you got all the stuff in completeList

由于我太懒了而无法仔细阅读它,因此我在这里跳过了您的案子,所以在您的情况下会是

Future<SearchResult1> fut1=service1.search(params);

Future<SerchResult2> fut2 = service2.search(params);

model.addAttribute("list1", fut1.get());

model.addAttribute("list2", fut2.get());

或类似的东西

答案 1 :(得分:0)

您可以使用执行程序服务提交线程,然后等待线程返回,然后继续:

@RequestMapping(path = "search", method = RequestMethod.POST)
public String searchPage(@ModelAttribute("specification") Specification specification, Model model) throws InterruptedException {

  ExecutorService executor = Executors.newCachedThreadPool();

  List<Callable<Map<String, List<?>>>> callables = new ArrayList<>();

  Callable<Map<String, List<?>>> callable1 = new Callable<Map<String,List<?>>>() {

    @Override
    public Map<String, List<?>> call() throws Exception {
      Map<String, List<String>> map = new HashMap<>();
      map.put("list1", service1.search(params));
      return map;
    }
  };
  callables.add(callable1);

  Callable<Map<String, List<?>>> callable2 = new Callable<Map<String,List<?>>>() {

    @Override
    public Map<String, List<?>> call() throws Exception {
      Map<String, List<String>> map = new HashMap<>();
      map.put("list2", service2.search(params));
      return map;
    }
  };
  callables.add(callable2);

  List<Future<Map<String, List<?>>>> futures = executor.invokeAll(callables);

  for (Future<Map<String, List<?>>> f : futures) {
    Map<String, List<?>> results = f.get();
    Entry<String, List<?>> res = results.entrySet().iterator().next();
    model.addAttribute(res.getKey(), res.getValue());
  }

  return "home";
}

基本上,您将提交这些任务,对future.get()的呼叫将等待返回。我将其略微更改,以便结果显示在地图中,其中键是列表名称,值是搜索结果。