我有一个弹簧组件EventSvcFacade,它具有三个EventValidationSvc实现类实例的列表。这些类中的每一个都实现方法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;
}
}
第一种方法更干净,因为它是pure:由于它不依赖于副作用,因此以后修改代码时,更容易推理,也不太可能破坏代码。
而且第一种方法也不像第二种方法对CountDownLatch
实例那样依赖于临时同步结构。如果您的前提条件发生变化,并且只有两个服务可以调用,则第一种方法将继续起作用,而第二种方法将永远不会返回。