¿Cómo hacer que un hilo de Java espere la salida de otro hilo?
Estoy creando una aplicación Java con un subproceso lógico de aplicación y un subproceso de acceso a la base de datos. Ambos persisten durante toda la vida útil de la aplicación y ambos deben ejecutarse al mismo tiempo (uno habla con el servidor, el otro habla con el usuario; cuando la aplicación se inicia por completo, necesito que ambos funcionen).
Sin embargo, al inicio, debo asegurarme de que inicialmente el subproceso de la aplicación espere hasta que el subproceso de la base de datos esté listo (actualmente determinado mediante el sondeo de un método personalizado dbthread.isReady()
). No me importaría si el hilo de la aplicación se bloquea hasta que el hilo de la base de datos esté listo.
Thread.join()
no parece una solución: el hilo de la base de datos solo sale cuando se cierra la aplicación.
while (!dbthread.isReady()) {}
Más o menos funciona, pero el bucle vacío consume muchos ciclos de procesador.
¿Alguna otra idea? Gracias.
Utilice un CountDownLatch con un contador de 1.
CountDownLatch latch = new CountDownLatch(1);
Ahora en el hilo de la aplicación haz-
latch.await();
En el hilo de la base de datos, una vez que haya terminado, haga:
latch.countDown();
Realmente recomendaría que sigas un tutorial como Java Concurrency de Sun antes de comenzar en el mundo mágico del subproceso múltiple.
También hay varios buenos libros (busque en Google "Programación concurrente en Java", "Concurrencia de Java en la práctica").
Para llegar a su respuesta:
En tu código que debe esperar el dbThread
, debes tener algo como esto:
//do some work
synchronized(objectYouNeedToLockOn){
while (!dbThread.isReady()){
objectYouNeedToLockOn.wait();
}
}
//continue with work after dbThread is ready
En su dbThread
método, necesitaría hacer algo como esto:
//do db work
synchronized(objectYouNeedToLockOn){
//set ready flag to true (so isReady returns true)
ready = true;
objectYouNeedToLockOn.notifyAll();
}
//end thread run method here
Lo que objectYouNeedToLockOn
estoy usando en estos ejemplos es preferiblemente el objeto que necesita manipular simultáneamente desde cada hilo, o podría crear uno separado Object
para ese propósito (no recomendaría sincronizar los métodos):
private final Object lock = new Object();
//now use lock in your synchronized blocks
Para mejorar su comprensión:
hay otras formas (a veces mejores) de hacer lo anterior, por ejemplo, con CountdownLatches
, etc. Desde Java 5, hay muchas clases de concurrencia ingeniosas en el java.util.concurrent
paquete y los subpaquetes. Realmente necesitas encontrar material en línea para conocer la concurrencia o conseguir un buen libro.