2009-09-10 5 views
6

Tengo una serie de tareas simultáneas para ejecutar. Si alguno de ellos falla, quiero interrumpirlos a todos y esperar la finalización. Pero suponiendo que ninguno de ellos falle, quiero esperar a que todos terminen.En Java, ¿cómo espero todas las tareas, pero me detengo al primer error?

ExecutorCompletionService parece casi lo que quiero aquí, pero no parece haber una forma de saber si todas mis tareas están hechas, excepto al mantener un conteo separado del número de tareas. (Tenga en cuenta que ambos ejemplos de Javadoc for ExecutorCompletionService hacen un seguimiento del recuento "n" de las tareas y lo utilizan para determinar si el servicio ha finalizado)

¿Estoy pasando por alto algo, o realmente lo hago? tengo que escribir este código yo mismo?

Respuesta

2

Sí, necesita realizar un seguimiento si está utilizando ExecutorCompletionService. Normalmente, debe llamar a get() en los futuros para ver si se produjo un error. Sin iterar sobre las tareas, ¿de qué otra manera podría decirse que falló?

+0

Podía manejar la condición de error en la tarea, pero sí, llamar a get() en el futuro es lo mejor. –

+0

Necesito iterar sobre las tareas, por supuesto, pero puedo tomar() el futuro de ExecutorCompletionService. (Esto es lo que hace el ejemplo de Javadoc). El problema es que no puedo simplemente tomar() hasta que me quedo sin tareas, porque si tomo() cuando no queda trabajo, me quedaré esperando por siempre. –

+1

Correcto, por lo que necesita precalcular el número de tareas (como pensaba), y tomar eso muchas veces. –

1

Si su serie de tareas es de un tamaño conocido, entonces debe usar el segundo ejemplo en el javadoc.

Sin embargo, si no conoce la cantidad de tareas que va a enviar al CompletionService, entonces tiene una especie de problema Productor-Consumidor. Un hilo está produciendo tareas y colocándolos en el ECS, otro estaría consumiendo los futuros de tareas a través de take(). Se podría usar un semáforo compartido, permitiendo al productor llamar a la versión() y al consumidor para llamar a adquirir(). La semántica de finalización dependerá de su aplicación, pero bastaría con un booleano volátil o atómico en el productor para indicar que está hecho.

Sugiero un Semaphore over wait/notify con poll() porque hay un retraso no determinista entre el momento en que se produce una tarea y el tiempo que el futuro de esa tarea está disponible para el consumo. Por lo tanto, el consumidor y el productor deben ser un poco más inteligentes.

+0

En realidad, en mi caso, solo tengo un hilo principal que produce las tareas y consume el futuro. Ciertamente puedo hacer que ese hilo mantenga un seguimiento determinista del recuento de tareas, pero parece extraño que deba hacerlo. –

Cuestiones relacionadas