¿Cómo esperar a Tema principal hasta métodos asincrónicos terminarán?

janusz j:

Tengo Service.class con start()el método:

public void start()  {  
    for (int i = 0; i < companiesList.size(); i++) {
        asychronous.someAsynchronous(...);
    }
    log.info("Start method has finished");
}

Tengo Asynchronous.class con someAsynchronous()el método:

@Async("threadPoolTaskExecutor")
public CompletableFuture<Void> someAsynchronous(some_parameters) {
    //do some stuff
    return null;
}

Los log.info()aparece antes de someAsynchronous()los métodos ha terminado. Cómo obligarlo a esperar log.info()hasta que someSynchronous()los métodos en bucle terminarán? Por cierto: las discusiones asincrónicas están aún en marcha después de terminar bucle.

Nikolas:

Los CompletableFuture<Void>Se solicita a las llamadas a ser ejecutado, pero después todos ellos comienzan en hilos separados, los acabados para-loop y el registro se imprime incluso antes de que cualquiera de ellos terminaron. Esta es la ventaja del procesamiento asíncrono - que no se preocupan por sus resultados y cuánto tiempo se llevaron a ejecutar.

Para lograr lo desea, tiene que comprobar periódicamente si todos ellos están terminados antes de proceder a la outoput registro.

// Adds executions to the List
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < companiesList.size(); i++) {
    futures.add(asychronous.someAsynchronous(...));
}

// Periodical check
Iterator<CompletableFuture<Void>> iterator = futures.iterator();
while (iterator.hasNext()) {
    CompletableFuture<Void> future = iterator.next(); // get the next one
    if (future.isDone()) {                            // if finished...
        //...                                         // ... do an action
        iterator.remove();                            // ... and remove from the Iterator
    }
    if (!iterator.hasNext()) {                        // if you reach the end
        iterator = futures.iterator();                // ... repeat the remaining Futures
    }
}

log.info("Start method has finished");

Tenga en cuenta que este método no termina hasta que todas las ejecuciones se realizan.


Edit: Gracias a @Kayaman quien sugirió el uso de un solo método dedicado para que la sustitución de todo el Iteratorlógicas. El futuresdebe ser una matriz:

// Adds executions to the List
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < companiesList.size(); i++) {
    futures.add(asychronous.someAsynchronous(...));
}

// Join the completion of all the threads
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

log.info("Start method has finished");

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=404373&siteId=1
Recomendado
Clasificación