Каков наилучший подход для использования CompletableFuture при выполнении потока асинхронных задач? - PullRequest
1 голос
/ 28 апреля 2020

У меня есть пружинный компонент EventSvcFacade, который содержит список из трех экземпляров класса реализации EventValidationSv c. Каждый из этих классов реализует метод boolean validate(T request), принимает одни и те же входные данные, но вызывает различные входные данные API, обрабатывает результат и возвращает логическое значение. Этот поток, таким образом, предназначен для одновременного вызова. Я разобрался с двумя подходами, чтобы вернуть список логических значений из потока задач. Кто-нибудь может подсказать, по каким факторам один подход лучше другого или есть какой-то другой лучший подход?

@Component
public class EventSvcFacade {

    @Autowired
    private List<EventValidationSvc<EventRequest>> validationSvcs;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    public List<Boolean> firstApproach(){
      final List<CompletableFuture<Boolean>> futures = validationSvcs.stream().map(service -> 
            CompletableFuture.supplyAsync(() -> service.validate(eventRequest), threadPoolExecutor))
            .collect(Collectors.toList());                                                                                      
      final List<Boolean> values = futures.stream().map(CompletableFuture :: 
            join).collect(Collectors.toList());
      return values;
    }

    public List<Boolean> secondApproach() {
      final List<Boolean> values = Collections.synchronizedList(new ArrayList<>());
      final CountDownLatch countDownLatch = new CountDownLatch(validationSvcs.size());
      validationSvcs.stream().forEach(service -> CompletableFuture.runAsync(() -> {         
            try{
             values.add(service.validate(eventRequest));
            }finally{
             countDownLatch.countDown();
            }
          }, threadPoolExecutor)
      );
      countDownLatch.await();
      return values;
   }
}

1 Ответ

0 голосов
/ 28 апреля 2020

Первый подход более чистый, поскольку он чистый : поскольку он не основывается на побочных эффектах, его легче рассуждать и с меньшей вероятностью сломаться, если код будет изменен позже.

Кроме того, первый подход не основан на ad-ho c конструкциях синхронизации, как, например, второй подход с экземпляром CountDownLatch. Если ваши предварительные условия изменятся и вам нужно будет позвонить только двум службам, первый подход будет работать, а второй никогда не вернется.

...