Estoy escribiendo una aplicación que tiene 5 subprocesos que obtienen información de la web simultáneamente y llenan 5 campos diferentes en una clase de búfer.
Necesito validar los datos del búfer y almacenarlos en una base de datos cuando todos los subprocesos terminaron su trabajo.
¿Cómo puedo hacer esto (recibir una alerta cuando todos los hilos terminen su trabajo)?
java
multithreading
wait
RYN
fuente
fuente
Respuestas:
El enfoque que tomo es usar un ExecutorService para administrar grupos de subprocesos.
fuente
while(!es.awaitTermination(1, TimeUnit.MINUTES));
es.shutdown();
? ¿Qué pasa si escribo un código en el que ejecuté un hilo usandoes.execute(runnableObj_ZipMaking);
entry
bloque y enfinally
llaméboolean finshed = es.awaitTermination(10, TimeUnit.MINUTES);
. Así que supongo que esto debería esperar hasta que todos los hilos completen su trabajo o se agote el tiempo de espera (lo que sea primero). ¿Mi suposición es correcta? o llamar ashutdown()
es obligatorio?Puedes
join
a los hilos. La unión se bloquea hasta que se completa el hilo.Tenga en cuenta que
join
arroja unInterruptedException
. Tendrá que decidir qué hacer si eso sucede (por ejemplo, intente cancelar los otros hilos para evitar que se realice un trabajo innecesario).fuente
t.join();
significa que el hilo actual se bloquea hasta quet
termina el hilo . No afecta el hilot
.Eche un vistazo a varias soluciones.
join()
La API se ha introducido en las primeras versiones de Java. Algunas buenas alternativas están disponibles con este paquete concurrente desde el lanzamiento de JDK 1.5.ExecutorService # invokeAll ()
Consulte esta pregunta de SE relacionada para ver un ejemplo de código:
¿Cómo usar invokeAll () para permitir que todos los grupos de subprocesos hagan su tarea?
CountDownLatch
Consulte esta pregunta para conocer el uso de
CountDownLatch
¿Cómo esperar a que un hilo genere su propio hilo?
ForkJoinPool o newWorkStealingPool () en Ejecutores
Iterar a través de todos los objetos futuros creados después de enviar a
ExecutorService
fuente
Además de lo
Thread.join()
sugerido por otros, java 5 introdujo el marco ejecutor. Allí no trabajas conThread
objetos. En su lugar, enviar susCallable
oRunnable
los objetos a un ejecutor. Hay un ejecutor especial que está destinado a ejecutar múltiples tareas y devolver sus resultados fuera de orden. Ese es elExecutorCompletionService
:Luego, puede llamar repetidamente
take()
hasta que no haya másFuture<?>
objetos para devolver, lo que significa que todos están completados.Otra cosa que puede ser relevante, dependiendo de su escenario es
CyclicBarrier
.fuente
executor.submit
devuelve unFuture<?>
. Agregaría estos futuros a una lista y luego recorrería la lista llamandoget
a cada futuro.Executors
, por ejemplo,Executors.newCachedThreadPool
(o similar)Otra posibilidad es el
CountDownLatch
objeto, que es útil para situaciones simples: como conoces de antemano el número de subprocesos, lo inicializas con el recuento relevante y pasas la referencia del objeto a cada subproceso.Al completar su tarea, cada hilo llama, lo
CountDownLatch.countDown()
que disminuye el contador interno. El hilo principal, después de iniciar todos los demás, debe hacer elCountDownLatch.await()
llamada de bloqueo. Se liberará tan pronto como el contador interno llegue a 0.Tenga en cuenta que con este objeto también
InterruptedException
se puede lanzar un.fuente
Tú lo haces
Después de este ciclo for, puede estar seguro de que todos los subprocesos han terminado su trabajo.
fuente
Espere / bloquee el hilo principal hasta que otros hilos completen su trabajo.
Como se
@Ravindra babu
dijo se puede lograr de varias formas, pero mostrando con ejemplos.java.lang.Thread. join () Desde: 1.0
java.util.concurrent.CountDownLatch Desde: 1.5
.countDown()
«Disminuye el recuento del grupo de pestillos..await()
«Los métodos de espera se bloquean hasta que la cuenta actual llega a cero.Si lo creó
latchGroupCount = 4
,countDown()
debería llamarse 4 veces para que la cuenta sea 0. Entonces, esoawait()
liberará los hilos de bloqueo.Código de ejemplo de la clase Threaded
LatchTask
. Para probar el uso del enfoquejoiningThreads();
ylatchThreads();
del método principal.Marco de ejecución: podemos usar ExecutorService para crear un grupo de subprocesos y rastrear el progreso de las tareas asincrónicas con Future.
submit(Runnable)
,submit(Callable)
que devuelven Future Object. Al usar lafuture.get()
función, podemos bloquear el hilo principal hasta que los hilos de trabajo completen su trabajo.invokeAll(...)
- devuelve una lista de objetos Future a través de los cuales puede obtener los resultados de las ejecuciones de cada invocable.Encuentre un ejemplo de uso de interfaces ejecutables, invocables con el marco de ejecución.
@Ver también
fuente
Almacene los objetos Thread en alguna colección (como una Lista o un Conjunto), luego recorra la colección una vez que se inicien los hilos y llame a join () en los hilos.
fuente
Puede utilizar el método de unión Threadf # para este propósito.
fuente
Aunque no es relevante para el problema de OP, si está interesado en la sincronización (más precisamente, un encuentro) con exactamente un hilo, puede usar un Intercambiador
En mi caso, necesitaba pausar el hilo principal hasta que el hilo secundario hiciera algo, por ejemplo, completara su inicialización. Un CountDownLatch también funciona bien.
fuente
Se puede usar un servicio ejecutor para administrar múltiples subprocesos, incluido el estado y la finalización. Consulte http://programmingexamples.wikidot.com/executorservice
fuente
prueba esto, funcionará.
fuente
Tuve un problema similar y terminé usando Java 8 paraleloStream.
Es super simple y legible. Detrás de escena, está utilizando el grupo de unión de bifurcación de JVM predeterminado, lo que significa que esperará a que finalicen todos los hilos antes de continuar. Para mi caso, fue una buena solución, porque era el único paralelo en mi aplicación. Si tiene más de una transmisión en paralelo ejecutándose simultáneamente, lea el enlace a continuación.
Más información sobre corrientes paralelas aquí .
fuente
Las respuestas existentes dijeron que podría
join()
cada hilo.Pero hay varias formas de obtener la matriz / lista de subprocesos:
ThreadGroup
para administrar los hilos.El siguiente código utilizará el
ThreadGruop
enfoque. Primero crea un grupo, luego, cuando crea cada hilo, especifique el grupo en el constructor, más tarde podría obtener la matriz de hilos a través deThreadGroup.enumerate()
Código
SyncBlockLearn.java
El hilo principal esperará a que finalicen todos los hilos del grupo.
fuente
Creé un pequeño método auxiliar para esperar a que terminen algunos subprocesos:
fuente
Use esto en su hilo principal: while (! Ejecutor.isTerminated ()); Coloque esta línea de código después de iniciar todos los hilos del servicio ejecutor. Esto solo iniciará el hilo principal después de que todos los hilos iniciados por los ejecutores hayan finalizado. Asegúrese de llamar a executeor.shutdown (); antes del bucle anterior.
fuente