¿Cuál es una forma de simplemente esperar a que finalice todo el proceso enhebrado? Por ejemplo, digamos que tengo:
public class DoSomethingInAThread implements Runnable{
public static void main(String[] args) {
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread());
t.start();
}
// wait for all threads' run() methods to complete before continuing
}
public void run() {
// do something here
}
}
¿Cómo modifico esto para que el main()
método se detenga en el comentario hasta run()
que salgan todos los métodos de los hilos ? ¡Gracias!
java
multithreading
parallel-processing
wait
DivideByHero
fuente
fuente
Una forma sería hacer una
List
deThread
s, crear y lanzar cada hilo, mientras lo agrega a la lista. Una vez que todo esté lanzado, recorra la lista y llamejoin()
a cada uno. No importa en qué orden terminen de ejecutarse los subprocesos, todo lo que necesita saber es que para cuando el segundo ciclo termine de ejecutarse, todos los subprocesos se habrán completado.Un mejor enfoque es utilizar un ExecutorService y sus métodos asociados:
El uso de un ExecutorService (y todas las novedades de las utilidades de concurrencia de Java 5 ) es increíblemente flexible, y el ejemplo anterior apenas toca la superficie.
fuente
fuente
en lugar de
join()
, que es una API antigua, puede usar CountDownLatch . He modificado su código como se muestra a continuación para cumplir con sus requisitos.Explicacion :
CountDownLatch
se ha inicializado con un recuento dado 1000 según sus requisitos.Cada subproceso de trabajo
DoSomethingInAThread
disminuirá elCountDownLatch
, que se ha pasado en constructor.Hilo principal
CountDownLatchDemo
await()
hasta que el recuento se vuelva cero. Una vez que el recuento se haya convertido en cero, obtendrá la línea por debajo de la salida.Más información de la página de documentación de Oracle
Consulte la pregunta SE relacionada para conocer otras opciones:
espere hasta que todos los hilos terminen su trabajo en java
fuente
Evite la clase Thread por completo y en su lugar utilice las abstracciones más altas proporcionadas en java.util.concurrent
La clase ExecutorService proporciona el método invokeAll que parece hacer exactamente lo que quieres.
fuente
Considere usar
java.util.concurrent.CountDownLatch
. Ejemplos en javadocsfuente
Como sugirió Martin K,
java.util.concurrent.CountDownLatch
parece ser una mejor solución para esto. Solo agrego un ejemplo para el mismofuente
Dependiendo de sus necesidades, es posible que también desee consultar las clases CountDownLatch y CyclicBarrier en el paquete java.util.concurrent. Pueden ser útiles si desea que sus subprocesos se esperen entre sí, o si desea un control más detallado sobre la forma en que se ejecutan sus subprocesos (por ejemplo, esperar en su ejecución interna a que otro subproceso establezca algún estado). También puede usar CountDownLatch para indicar a todos sus hilos que comiencen al mismo tiempo, en lugar de comenzarlos uno por uno mientras recorre su ciclo. Los documentos de la API estándar tienen un ejemplo de esto, además de usar otro CountDownLatch para esperar a que todos los subprocesos completen su ejecución.
fuente
Si hace una lista de los hilos, puede recorrerlos y .join () contra cada uno, y su bucle terminará cuando todos los hilos hayan terminado. Aunque no lo he probado.
http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join ()
fuente
Crea el objeto hilo dentro del primer bucle for.
Y luego lo que todos aquí están diciendo.
fuente
Puedes hacerlo con el Objeto "ThreadGroup" y su parámetro activeCount :
fuente
Como alternativa a CountDownLatch , también puede utilizar CyclicBarrier, por ejemplo
Para usar CyclicBarrier en este caso, el valor de la barrera.await () debería ser la última declaración, es decir, cuando el hilo haya terminado con su trabajo. CyclicBarrier se puede usar de nuevo con su método reset (). Para citar javadocs:
Un CyclicBarrier admite un comando Runnable opcional que se ejecuta una vez por punto de barrera, después de que llega el último hilo del grupo, pero antes de que se libere cualquier hilo. Esta acción de barrera es útil para actualizar el estado compartido antes de que cualquiera de las partes continúe.
fuente
El
join()
no era útil para mí. vea esta muestra en Kotlin:El resultado:
Ahora déjame usar el
join()
for hilos:Y el resultado:
Como queda claro cuando usamos
join
:Nuestra solución para evitar el bloqueo de otros subprocesos fue crear una ArrayList:
Ahora, cuando queremos comenzar un nuevo hilo, lo agregamos a ArrayList:
La
addThreadToArray
función:La
startNewThread
función:Verifique la finalización de los hilos como se muestra a continuación en todos los lugares donde sea necesario:
fuente