Estoy usando multi-threading en java para mi programa. He corrido satisfactoriamente el hilo, pero cuando estoy usando Thread.wait()
, arroja java.lang.IllegalMonitorStateException
. ¿Cómo puedo hacer que un hilo espere hasta que se lo notifiquen?IllegalMonitorStateException en wait() call
Respuesta
Debe estar en un bloque synchronized
para que Object.wait()
funcione.
Además, recomiendo ver los paquetes de simultaneidad en lugar de los paquetes de subprocesamiento de la vieja escuela. Son más seguros y mucho menos easier to work with.
Happy coding.
EDITAR
Supuse que quería decir Object.wait()
como su excepción es lo que sucede cuando se intenta acceder sin sostener bloquean los objetos.
Como no ha publicado el código, estamos trabajando en la oscuridad. ¿Cuáles son los detalles de la excepción?
¿Está llamando a Thread.wait() desde el hilo o fuera de él?
lo pregunto porque de acuerdo con el Javadoc para IllegalMonitorStateException, es:
Lanzado para indicar que un mensaje ha tratado de esperar en el monitor de un objeto o para notificar a otros hilos que esperan en el monitor de un objeto sin ser dueño del monitor especificado.
Para aclarar esta respuesta, esta llamada a esperar en un hilo también lanza IllegalMonitorStateException, a pesar de ser llamado desde dentro de un bloque sincronizado:
private static final class Lock { }
private final Object lock = new Lock();
@Test
public void testRun() {
ThreadWorker worker = new ThreadWorker();
System.out.println ("Starting worker");
worker.start();
System.out.println ("Worker started - telling it to wait");
try {
synchronized (lock) {
worker.wait();
}
} catch (InterruptedException e1) {
String msg = "InterruptedException: [" + e1.getLocalizedMessage() + "]";
System.out.println (msg);
e1.printStackTrace();
System.out.flush();
}
System.out.println ("Worker done waiting, we're now waiting for it by joining");
try {
worker.join();
} catch (InterruptedException ex) { }
}
@CPerkins: Creo que estás confundiendo el hilo de ejecución y el objeto que es el objetivo de 'wait()'. –
@Robert - Quizás sí, pero no lo creo. Si comienza una instancia Thread y luego le pide que espere, obtendrá IllegalMonitorStateException, que es lo que estaba tratando de describir. – CPerkins
¿Estás hablando de la línea 'worker.wait()'? Entonces deberías estar sincronizando con el trabajador, no con el candado. –
wait
se define en Object
, y no se Thread
. El monitor en Thread
es un poco impredecible.
A pesar de todos los objetos de Java tienen monitores, generalmente es mejor tener una cerradura dedicado:
private final Object lock = new Object();
Puede obtener un poco más fácil de leer el diagnóstico, en un pequeño coste de memoria (alrededor de 2K por proceso) mediante el uso de una clase llamada:
private static final class Lock { }
private final Object lock = new Lock();
con el fin de wait
o notify
/notifyAll
un objeto, tiene que ser la celebración de la cerradura con la declaración synchronized
. Además, necesitará un bucle while
para verificar la condición de activación (busque un buen texto en el subproceso para explicar por qué).
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
a notificar:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
Vale la pena llegar a comprender tanto el lenguaje Java y java.util.concurrent.locks
cerraduras (y java.util.concurrent.atomic
) al entrar en multihilo.Pero use java.util.concurrent
estructuras de datos siempre que pueda.
Nunca he entendido cómo funciona esto, dado que la espera y la notificación están ambas en bloques sincronizados en el mismo objeto (bloqueo). Como el hilo de espera está en el bloque, ¿no debería eso hacer que el bloque de hilos de notificación esté en la línea "sincronizada (bloqueo)"? – Brent212
@ Brent212 Para cualquier otro método que no sea 'wait', sí, nunca llegarás a' notify'. Sin embargo, en los documentos API para 'Object.wait'," El hilo libera la propiedad de este monitor ". Por lo tanto, mientras está "esperando" es como si estuviera fuera de los bloques 'sincronizados' que lo contienen (para el mismo objeto, puede haber múltiples bloques' sincronizados' en el mismo objeto). –
La llamada a Thread.wait() tiene sentido dentro de un código que se sincroniza en el objeto Thread.class. No creo que sea lo que querías decir.
Usted pregunta
¿Cómo puedo hacer una espera hasta que el hilo se notificará?
Solo puede esperar el hilo actual. Cualquier otro hilo se puede pedir suavemente que espere, si está de acuerdo.
Si desea esperar alguna condición, necesita un objeto de bloqueo: el objeto Thread.class es una opción muy mala: es un AFAIK de singleton, por lo que sincronizarlo (excepto para los métodos estáticos de subprocesos) es peligroso.
Los detalles para la sincronización y la espera ya han sido explicados por Tom Hawtin. java.lang.IllegalMonitorStateException
significa que está intentando esperar un objeto en el que no está sincronizado; es ilegal hacerlo.
Sobre la base de sus comentarios Parece que usted está haciendo algo como esto:
Thread thread = new Thread(new Runnable(){
public void run() { // do stuff }});
thread.start();
...
thread.wait();
hay dos problemas. En primer lugar, como han dicho otros, obj.wait()
solo se puede invocar si el hilo actual contiene el mutex primitivo para obj
. Si el hilo actual no contiene el mutex, obtienes la excepción que estás viendo.
El segundo (más importante) problema es que thread.wait()
no hace lo que parece estar esperando que haga. Específicamente, thread.wait()
no hace causa que el subproceso designado espere. Más bien ocasiona que el hilo actual espere hasta que otro hilo llame a thread.notify()
o thread.notifyAll()
.
En realidad, no existe una forma segura de forzar a una instancia de subproceso a pausar si no lo desea. (El más cercano que Java tiene que esta es la obsoleta Thread.suspend()
método, pero ese método es inherentemente insegura, como se explica en el Javadoc.)
Si desea que el hilo recién iniciada para hacer una pausa, la mejor manera de hacerlo es para crear una instancia de CountdownLatch y hacer que el hilo llame al await()
en el pestillo para pausarlo. El hilo principal llamaría al countDown()
en el pestillo para permitir que el hilo pausado continúe.
Sé que este hilo es de casi 2 años, pero todavía tienen que cerrar esto ya que también vine a este Q/A con mismo problema ...
Lea esta definición de illegalMonitorException una y otra vez ..
IllegalMonitorException se emite para indicar que un subproceso ha intentado esperar en el monitor de un objeto o para notificar a otros subprocesos que esperan en el monitor de un objeto sin ser propietarios del monitor especificado.
Esta línea dice una y otra vez, IllegalMonitorException viene cuando se produce uno de los 2 ....
situación1> esperar en el monitor de un objeto sin tener que poseer el monitor especificado.
2> notificar a otros subprocesos que esperan en el monitor de un objeto sin ser propietarios del monitor especificado.
Algunos podrían haber conseguido sus respuestas ... que todo no, entonces por favor revise las declaraciones 2 ....
sincronizada (objeto)
Object.wait()
Si ambos objeto son lo mismo ... entonces no se puede obtener la excepción illegalMonitorException.
Ahora, de nuevo, lea la definición IllegalMonitorException y que no se olvidará de nuevo ...
En realidad, eso no funciona. Lo intenté Creo un Runnable, lo encierro (usando el bloque sincronizado) y dentro de ese bloque ejecuto Runnable en el UI-thread (Android) y luego hago myRunnable.wait(), y aún obtengo la excepción. – Ted
Excelente explicación !! Estaba haciendo wait() sin especificar el objeto, por lo que tomó la instancia y la sincronización en otro objeto. Ahora estoy usando otherObject.wait() y funciona! – Fersca
No estoy seguro si esto va a ayudar a otra persona a cabo o no, pero esta fue la pieza clave para solucionar mi problema en el usuario "Tom Hawtin - tacklin " 's respuesta anterior:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
Sólo el hecho de que el 'bloqueo' se pasa como un argumento en sincronizado (es) y que también se utiliza en 'bloquear' .notifyAll();
Una vez lo hice en esos 2 lugares a los que tiene que trabajar
recibí una IllegalMonitorStateException
al tratar de despertar un hilo en/desde un class
/subproceso diferente. En java 8
puede usar las funciones lock
features of the new Concurrency APIen su lugar de synchronized
.
Ya estaba almacenando objetos para transacciones de websocket asynchronous
en un WeakHashMap
. La solución en mi caso también fue store a lock
object in a ConcurrentHashMap
para synchronous
respuestas. Notacondition.await
(no .wait
).
Para manejar el multi-threading utilicé un Executors.newCachedThreadPool()
para crear un thread pool.
Los que están utilizando la versión de Java 7.0 o inferior pueden referir el código que utilicé aquí y funciona.
public class WaitTest {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitHere(long waitTime) {
System.out.println("wait started...");
lock.lock();
try {
condition.await(waitTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println("wait ends here...");
}
public static void main(String[] args) {
//Your Code
new WaitTest().waitHere(10);
//Your Code
}
}
- 1. IllegalMonitorStateException
- 2. IllegalMonitorStateException
- 3. driver.wait() arroja IllegalMonitorStateException
- 4. wait() en Servlet throws Excepción
- 5. Java Delay/Wait
- 6. ERLANG wait() y bloqueo
- 7. Windows Threading Wait Método
- 8. de desbloqueo de ReentrantLock sin IllegalMonitorStateException
- 9. Cómo evitar IllegalMonitorStateException al usar lockInterruptibly en Reentrantlock
- 10. ¿Por qué notifyAll() genera IllegalMonitorStateException cuando se sincroniza en Integer?
- 11. Java Thread wait() => bloqueado?
- 12. Monitor.Pulse y Wait - Comportamiento inesperado
- 13. ¿Cómo usar wait and notify en Java?
- 14. ¿Qué hace synchronized()/wait()/notifyAll() en Java?
- 15. función wait() o sleep() en jquery?
- 16. Semaphore.WaitOne/Release vs Monitor.Pulse/Wait
- 17. Wait on startService before bindService
- 18. ¿Cómo funciona 'call' en javascript?
- 19. patrones "call-cc" en Scala?
- 20. Método anónimo en Invoke call
- 21. Html.RenderPartial call from masterpage
- 22. javascript setTimeout call error
- 23. ¿Qué es call/cc?
- 24. call gettid witin glibc
- 25. Cómo inspeccionar Call Stack
- 26. Imprimir PHP Call Stack
- 27. Vi - ": call append()"
- 28. Detalles de call/cc
- 29. erlang call stack
- 30. FileSystemWatcher Dispose call cuelga
Thread.wait() no existe, podría ser this.wait() – Premraj