Estoy tratando de entender CompletableFuture
y cómo puedo utilizarlo para construir un objeto con la información obtenida a partir de varios criterios de valoración. Me he encontrado con algunos ejemplos, pero ninguno es adaptado a mi problema. Por ejemplo, éste se está ejecutando el mismo método en paralelo para obtener una lista de cadenas en el que necesito para ejecutar múltiples métodos en paralelo para construir y devolver un objeto.
He creado un DTO simple para un empleado:
@Builder
@Data
@AllArgsConstructor
public class EmployeeDTO {
private String name;
private String accountNumber;
private int salary;
}
He creado un servicio de llamadas imitan a tres API separados para establecer los valores de la DTO con un tiempo de espera considerable:
public class EmployeeService {
public EmployeeDTO setName() {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return EmployeeDTO.builder().name("John Doe").build();
}
public EmployeeDTO setAccountNumber() {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return EmployeeDTO.builder().accountNumber("1235").build();
}
public EmployeeDTO setSalary() {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return EmployeeDTO.builder().salary(100000).build();
}
}
Puedo supplyAsync
los tres de los métodos y vuelva a ejecutar allOf
pero no hacer nada:
private void run() {
EmployeeService employeeService = new EmployeeService();
CompletableFuture<EmployeeDTO> employeeCfWithName = CompletableFuture
.supplyAsync(employeeService::setName);
CompletableFuture<EmployeeDTO> employeeCfWithAccountNumber = CompletableFuture
.supplyAsync(employeeService::setAccountNumber);
CompletableFuture<EmployeeDTO> employeeCfWithSalary = CompletableFuture
.supplyAsync(employeeService::setSalary);
CompletableFuture allCompletableFutures = CompletableFuture.allOf(employeeCfWithName, employeeCfWithAccountNumber, employeeCfWithSalary);
}
¿Cómo puedo combinar los resultados en una sola EmployeeDTO?
Usted tendrá que combinar los resultados de los tres CompletableFuture
s en una sola EmployeeDTO
. Esto no se hace por arte de magia allOf
.
Intentar algo como esto (no probado):
CompletableFuture allCompletableFutures = CompletableFuture.allOf(
employeeCfWithName, employeeCfWithAccountNumber, employeeCfWithSalary);
// Wait for all three to complete.
allCompletableFutures.get();
// Now join all three and combine the results.
EmployeeDTO finalResult = EmployeeDTO.builder()
.name(new employeeCfWithName.join())
.accountNumber(new employeeCfWithAccountNumber.join())
.salary(new employeeCfWithSalary.join())
.build();
Esto parece un poco tonta. Utilizamos un constructor en cada método sólo para combinar sus resultados utilizando una cuarta constructor.