Esperando un subconjunto de subprocesos en un ThreadPool de Java

Digamos que tengo un grupo de subprocesos que contiene X elementos, y una tarea dada emplea Y de estos elementos (donde Y es mucho más pequeño que X).

Quiero esperar todos los hilos de una tarea determinada (Y elementos) para terminar, no todo el grupo de subprocesos.

Si el grupo de subprocesos execute() El método devolvió una referencia al hilo empleado que simplemente podría join() a cada uno de estos Y hilos, pero no es así.

¿Alguien conoce una forma elegante de lograr esto? Gracias.

preguntado el 08 de enero de 11 a las 17:01

4 Respuestas

En lugar de execute()Ing. Runnables, solo invokeAll() algo Callables - entonces obtienes un Future para cada uno en el que puede llamar get(), que se bloquea hasta que finaliza la tarea.

Respondido el 08 de enero de 11 a las 20:01

Puede utilizar CyclicBarrier y hacer que cada hilo espere solo cuando sea de tipo Y. Por ejemplo.

ExecutorService executor = Executors.newFixedThreadPool(X.size);

public void executeAllAndAwaitCompletion(List<? extends Y> myRunnableY){
   final CyclicBarrier barrier = new CyclicBarrier(myRunnable.size()+1);
   for(final Y y : myRunnableY){
       executor.submit(new Runnable(){
           public void run(){
                y.run();//for the sake of this example y has a run method
                barrier.await();
           }
       }); 
    }
   barrier.await();
}

Entonces, cada subproceso que se está ejecutando tipo Y esperará hasta que se hayan completado todos esos Y. Tenga en cuenta que debe agregar 1 al tamaño de la barrera para tener en cuenta que el subproceso que se ejecuta inicialmente también debe esperar.

También tenga en cuenta: si el ejemplo de Michael Borgwardt funciona para usted, sería lo mejor. Sin embargo, si necesita el grupo de subprocesos, para cada subproceso que ejecuta Y para que no ejecute ningún otro que no sea Y, entonces mi solución sería la única forma en que puede hacerlo. Future.

Respondido el 08 de enero de 11 a las 21:01

Eso es realmente genial, gracias, pero todas las tareas son del mismo tipo (solo pertenecen a diferentes padres). - David Semeria

Oh, ya veo, todavía puede usar ese mecanismo en consecuencia, solo haría que los padres y tengan una referencia a la barrera cíclica y luego puedan esperar en consecuencia. De lo contrario, conoce una forma diferente de sincronización :) - John Vint

Deberías usar un CompletionService que se utiliza exactamente para este propósito.

  • Crear Executor
  • Crear ExecutorCompletionService usando el Ejecutor
  • Envíe tareas a través del CompletionService
  • Utilización de take or poll en CompletionService para esperar a que finalicen las tareas
  • Repita hasta que todas las tareas que envió hayan finalizado.
  • Terminados

Puedes compartir un Ejecutor con otra cosa, solo crea el CompletionService en la parte superior y utilícelo para sus tareas específicas.

Respondido el 08 de enero de 11 a las 22:01

Crear CountDownLatch es Y como contar y hacer latch.countDown() en cada Y Tareas. Al final latch.await() se asegurará de que todos los Y se completan las tareas.

respondido 30 nov., 13:14

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.