Estoy usando ExecutorService para facilitar el programa multiproceso concurrente. Tomar siguiente código:ExecutorService, forma estándar para evitar que la cola de tareas se llene demasiado
while(xxx)
ExecutorService exService = Executors.newFixedThreadPool(NUMBER_THREADS);
...
Future<..> ... = exService.submit(..);
...
}
En mi caso, el problema es que enviar() no se bloquea si están ocupados todos los NUMBER_THREADS. La consecuencia es que la cola de Tareas se inunda con muchas tareas. La consecuencia de esto es que el cierre del servicio de ejecución con ExecutorService.shutdown() lleva años (ExecutorService.isTerminated() será falso durante mucho tiempo). La razón es que la cola de tareas todavía está bastante llena.
Por ahora mi solución es trabajar con semáforos para no permitir a tener que muchas entradas dentro de la cola de tareas de ExecutorService:
...
Semaphore semaphore=new Semaphore(NUMBER_THREADS);
while(xxx)
ExecutorService exService = Executors.newFixedThreadPool(NUMBER_THREADS);
...
semaphore.aquire();
// internally the task calls a finish callback, which invokes semaphore.release()
// -> now another task is added to queue
Future<..> ... = exService.submit(..);
...
}
Estoy seguro de que hay una solución mejor y más encapsulado?
veo. pasé por alto un detalle en http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29. allí se menciona que, como estándar, se utiliza una cola sin límites. –
lo probé. desafortunadamente, su solución no se bloquea (como yo quiero) sino que arroja una excepción RejectedExecutionException. también encontrado: http://www.velocityreviews.com/forums/t389526-threadpoolexecutor-with-blocking-execute.html. las soluciones presentadas parecen ser más complicadas que mi ejemplo de semáforo, ¡maldita sea! –
esto no funciona debido a RejectedExecutionException si la cola está llena – user249654