Posteriormente a indagar en diferentes repositorios y foros de internet finalmente nos encontramos con la resolución que te compartiremos ahora.
Solución:
Deberías repetir awaitTermination
ExecutorService threads;
// ...
// Tell threads to finish off.
threads.shutdown();
// Wait for everything to finish.
while (!threads.awaitTermination(10, TimeUnit.SECONDS))
log.info("Awaiting completion of threads.");
Tu problema parece ser que no estás llamando shutdown
después de haber enviado todos los trabajos a su grupo. Sin shutdown()
su awaitTermination
siempre volveré false.
ThreadPoolExecutor ex =
new ThreadPoolExecutor(limit, limit, 20, TimeUnit.SECONDS, q);
for (int i = 0; i < limit; i++)
ex.execute(new RunnableObject(i + 1));
// you are missing this line!!
ex.shutdown();
ex.awaitTermination(2, TimeUnit.SECONDS);
También puede hacer algo como lo siguiente para esperar a que terminen todos sus trabajos:
List> futures = new ArrayList>();
for (int i = 0; i < limit; i++)
futures.add(ex.submit(new RunnableObject(i + 1), (Object)null));
for (Future
Además, porque estás durmiendo por 2354
milisegundos, pero solo esperando la terminación de todos los trabajos para 2
SECONDS
, awaitTermination
siempre volveré false
. yo usaría Long.MAX_VALUE
esperar a que terminen los trabajos.
Por último, parece que te preocupa crear un nuevo ThreadPoolExecutor
y en su lugar desea reutilizar el primero. no seas La sobrecarga de GC será extremadamente mínima en comparación con cualquier código que escriba para detectar si los trabajos están terminados.
Para citar de los javadocs, ThreadPoolExecutor.shutdown()
:
Inicia un apagado ordenado en el que se ejecutan las tareas enviadas anteriormente, pero no se aceptarán tareas nuevas. La invocación no tiene ningún efecto adicional si ya está cerrada.
En el ThreadPoolExecutor.awaitTermination(...)
método, está esperando que el estado del ejecutor vaya a TERMINATED
. Pero primero el estado debe ir a SHUTDOWN
Si shutdown()
se llama o STOP
Si shutdownNow()
se llama.
No tiene nada que ver con el ejecutor en sí. Solo usa la interfaz java.util.concurrent.ExecutorService.invokeAll(Collection extends Callable
. Se bloqueará hasta que todos los Callable
están terminados.
Los ejecutores están destinados a ser longevos; más allá del tiempo de vida de un grupo de tareas. shutdown
es para cuando la aplicación está terminada y limpia.
Eres capaz de corroborar nuestra faena fijando un comentario y dejando una valoración te damos las gracias.