Estoy llamando a un método asíncrono en el interior de bucle y la adición de futuro de la misma en una lista. No estoy seguro de por qué AllOff no está a la espera de completar todos los futuros y devolver resultado parcial. Echar un vistazo de mi código.
Tengo un método reemplazado
@Overide
@Async
CompletableFuture<someType> fetchData()
{
returns new CompletableFuture<someType>();
}
Estoy llamando el método anterior en un bucle for con diferentes instancias.
obtener todos los granos, que implments una interfaz que tiene mehod fetchData.
Map<String, SomeClass> allBeans =context.getBeansOfType(SomeClass.class);
List<SomeClass> list=
allBeans.values().stream().collect(SomeClass.toList());
for (SomeClass classInstance: list) {
classInstance.fetchData().thenApply(x->{
//Some DB persistence Call
futureList.add(x);
});
}
después de eso estoy solicitando AllOff de manera que todos los futuros se puede completar pero no está esperando a todos y hilo principal excuting resto del flujo.
CompletableFuture<Void> combinedFutures = CompletableFuture.allOf(
futureList.toArray(new CompletableFuture[futureList.size()]));
CompletableFuture<List<futureResponse>> finalList=
combinedFutures.thenApply(v -> {
return futureList.stream().map(m ->
m.join()).collect(Collectors.toList());
});
finalList- en la lista Quiero todos los futuros del completados devueltos por traen invocación.
En finalList Siempre estoy haciendo 2 objetos sino fetchData está llegando el correr 5 veces (según el número de casos), vi el registro después de permanecer toda la llamada asincrónica están siendo completado. Es posible que alguien ayuda aquí.
Observación: - Después de poner hilo principal sobre el sueño durante 30 segundos, pude ver que tengo los 5 objetos de la lista. ¿Podría alguien por favor explicar por qué hilo principal no está esperando en AllOff para todos los futuros para completar.
IIUC, lo que quiere hacer se puede hacer más simple haciendo
CompletableFuture<List<FutureResponse>> = CompletableFuture.supplyAsync(() -> {
// start fetches and collect the individual futures
List<CompletableFuture> fetches =
allBeans.values().stream()
.map(SomeClass::fetchData)
.collect(toList());
// join all futures and return the list of the results
return fetches.stream()
.map(CompletableFuture::join)
.collect(toList());
}
Creo que no se puede hacer en una sola corriente (es decir, asignar a fetch
, entonces inmediatamente a join
) porque eso podría esperar a la unión antes de crear el próximo futuro.