[英]How to make threads in ExecutorService to wait stage
在我的 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
。 如果任何一个延迟,逻辑将是错误的。 创建线程是昂贵的。
Stream
自动处理这种情况吗?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()
仍在运行。)不,Streams 不负责加入这些线程。
由于您等待这 3 个线程的结果并将它们放入您返回的 map 中,因此只要您必须等待并返回结果,将此类逻辑包装在单独的线程中对您没有帮助。
使用ExecutorService::invokeAll
执行所有任务并在所有任务完成时返回 Futures 列表(当Future::done
为true
时)。
List<Future<List<Object>>> list = service.invokeAll( Arrays.asList( () -> someService.method_a(), () -> someService.method_b(), () -> someService.method_c() ));
请注意,这些是有保证的:
List<Future>
与给定任务集合的顺序相同(根据其Iterator
)。此逻辑可帮助您处理完整的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.