有 Java 编程相关的问题?

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

java如何使ExecutorService中的线程处于等待阶段

在我的web应用程序中,我需要在一个API调用中调用大约10个以上的方法。为了提高效率,我使用ExecutorService同时创建多个线程。每个返回不同对象的方法都需要fav_a(), fav_b(), fav_c()。(为了方便起见,下面给出了示例代码)

@GetMapping(RequestUrl.INIT)
public ResponseEntity<Map<String, List<?>>> init() throws ExecutionException, InterruptedException {

    ExecutorService service = Executors.newFixedThreadPool(6);

    Future<List<Object>> method_a = service.submit(() -> someService.method_a());
    Future<List<Object>> method_b = service.submit(() -> someService.method_b());
    Future<List<Object>> method_c = service.submit(() -> someService.method_c());       
    
    Future<List<FavouriteConverter>> fav_a = service.submit(() -> someService.fav_a());
    Future<List<FavouriteConverter>> fav_b = service.submit(() -> someService.fav_b());
    Future<List<FavouriteConverter>> fav_c = service.submit(() -> someService.fav_c());

    service.shutdown();

    List<FavouriteConverter> combinedFavourite = Stream.of(fav_a.get(), fav_b.get(), fav_c.get()).flatMap(f -> f.stream()).collect(Collectors.toList());
    combinedFavourite=combinedFavourite.stream()
            .sorted(Comparator.comparing(FavouriteConverter::get_id, Comparator.reverseOrder()))
            .limit(25)
            .collect(Collectors.toList());

    Map<String, List<?>> map = new HashMap<>();    

    map.put("method_a", method_a.get());
    map.put("method_b", method_b.get());
    map.put("method_c", method_c.get());
    map.put("favourite", combinedFavourite);

    return new ResponseEntity<>(map, HttpStatus.OK);

}

首先我需要让fav_a.get(), fav_b.get(), fav_c.get()来制作combinedFavourite。如果其中任何一个延迟,逻辑将是错误的。创建线程非常昂贵

  1. Stream会自动处理这种情况吗
  2. 如果fav_a(), fav_b(), fav_c()比其他方法更早地完成它的工作,我如何将combinedFavourite放入另一个线程?这意味着如何使Future<List<FavouriteConverter>> combinedFavourite处于等待阶段,直到fav_a.get(), fav_b.get(), fav_c.get()完成。(假设method_a(),method_b(),method_c()仍在运行。)

共 (1) 个答案

  1. # 1 楼答案

    1. 不,流不负责连接这些线程

    2. 由于您等待这3个线程的结果,并将它们放入一个映射中,然后返回,因此,只要您必须等待并返回结果,将此类逻辑包装在单独的线程中是没有帮助的

      使用^{}执行所有任务,并在所有任务完成后返回一个未来列表(当Future::donetrue

      List<Future<List<Object>>> list = service.invokeAll(
          Arrays.asList(
              () -> someService.method_a(),
              () -> someService.method_b(),
              () -> someService.method_c()
      ));
      

      注意:这些是有保证的:

      • 结果List<Future>与给定任务集合的顺序相同(根据其Iterator
      • 如果线程池中的线程数高于或等于已执行的任务(假设没有其他任务使用同一线程池中的线程),则所有任务都将在单独的线程中运行

    这个逻辑帮助你获得完整的结果