Supongamos que tenemos un conjunto de tareas A, B, C, D, E
y que desea ejecutar cada uno de ellos de forma asíncrona en un Executor
y procesar los resultados del 1 por 1 mientras completan.
Con una Executor
, que lo haría así:
List<Future<?>> futures = new ArrayList<Future<?>>();
futures.add(executorService.submit(A));
futures.add(executorService.submit(B));
futures.add(executorService.submit(C));
futures.add(executorService.submit(D));
futures.add(executorService.submit(E));
//This loop must process the tasks in the order they were submitted: A, B, C, D, E
for (Future<?> future:futures) {
? result = future.get();
// Some processing here
}
El problema con este método es que no hay garantía de que la tarea A
completará en primer lugar. Por lo tanto, es posible que el hilo principal bloquee ociosamente esperando que se complete la tarea A
cuando podría estar procesando el resultado de otra tarea (por ejemplo, la tarea B
). La latencia de procesamiento de resultados se puede reducir utilizando un ExecutorCompletionService
.
List<Future<?>> futures = new ArrayList<Future<?>>();
futures.add(executorCompletionService.submit(A));
futures.add(executorCompletionService.submit(B));
futures.add(executorCompletionService.submit(C));
futures.add(executorCompletionService.submit(D));
futures.add(executorCompletionService.submit(E));
//This for loop will process the tasks in the order they are completed,
//regardless of submission order
for (int i=0; i<futures.size(); i++) {
? result = executorCompletionService.take().get();
// Some processing here
}
Así que, en esencia, ExecutorCompletionService
podrían usarse para exprimir un poco más eficiencia cuando el orden de los resultados de las tareas de procesamiento no importa.
Sin embargo, una cosa importante a tener en cuenta. La implementación de ExecutorCompletionService contiene una cola de resultados. Si no se llama a take
o poll
para drenar esa cola, se producirá una pérdida de memoria. Algunas personas usan el Future
devuelto por submit
para procesar los resultados y este NO es el uso correcto.
el uso correcto es solo para crear el futuro;) – bestsss
Muchas gracias Tim por su apoyo. El ejemplo y la explicación son muy claros. –
Una respuesta tan increíble y solo obtuvo 18 votos hasta el momento. Esto me pone triste. Ese bebé se ve tan lindo en tus manos. –