Acabo de encontrar CompletionService en this blog post. Sin embargo, esto realmente no muestra las ventajas de CompletionService sobre un ExecutorService estándar. El mismo código se puede escribir con cualquiera. Entonces, ¿cuándo es útil un CompletionService?¿Cuándo debería usar un CompletionService en un ExecutorService?
¿Se puede dar una muestra de código corto para que sea claro como el cristal? Por ejemplo, este ejemplo de código demuestra que no se necesite un CompletionService (= equivalente a ExecutorService)
ExecutorService taskExecutor = Executors.newCachedThreadPool();
// CompletionService<Long> taskCompletionService =
// new ExecutorCompletionService<Long>(taskExecutor);
Callable<Long> callable = new Callable<Long>() {
@Override
public Long call() throws Exception {
return 1L;
}
};
Future<Long> future = // taskCompletionService.submit(callable);
taskExecutor.submit(callable);
while (!future.isDone()) {
// Do some work...
System.out.println("Working on something...");
}
try {
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
para otro ejemplo vea Java Concurrency in Practice pág. 130. Allí se usa un CompletionService para renderizar imágenes a medida que estén disponibles. – Pete
¿Es seguro asumir que 'take' y' poll' en CompletionService son seguros para subprocesos? En su ejemplo, las tareas todavía se están ejecutando cuando se invoca 'take()' por primera vez, y no veo ninguna sincronización explícita. – raffian
'take()' es seguro para hilos. Puedes leer en los JavaDocs pero básicamente 'take()' esperará el siguiente resultado completado y luego lo devolverá. El 'CompletionService' funciona con' BlockingQueue' para la salida. –