Estoy usando multi-threading en java para mi programa. He ejecutado el hilo con éxito, pero cuando lo estoy usando Thread.wait()
, está tirando java.lang.IllegalMonitorStateException
. ¿Cómo puedo hacer que un hilo espere hasta que sea notificado?
java
multithreading
wait
prakash.panjwani
fuente
fuente
Respuestas:
Debes estar en un
synchronized
bloque paraObject.wait()
poder trabajar.Además, recomiendo mirar los paquetes de concurrencia en lugar de los paquetes de subprocesos de la vieja escuela. Son más seguros y más fáciles de trabajar .
Feliz codificación
EDITAR
Supuse que querías decir
Object.wait()
que tu excepción es lo que sucede cuando intentas obtener acceso sin mantener el bloqueo de objetos.fuente
wait
se define enObject
, y no lo esThread
. El monitor encendidoThread
es un poco impredecible.Aunque todos los objetos Java tienen monitores, generalmente es mejor tener un bloqueo dedicado:
Puede obtener diagnósticos un poco más fáciles de leer, a un bajo costo de memoria (aproximadamente 2K por proceso) utilizando una clase con nombre:
Para /
wait
o un objeto, debe mantener el bloqueo con la declaración. Además, necesitará un bucle para verificar la condición de activación (busque un buen texto sobre subprocesos para explicar por qué).notify
notifyAll
synchronized
while
Notificar:
Vale la pena entender tanto el lenguaje Java como los
java.util.concurrent.locks
bloqueos (yjava.util.concurrent.atomic
) al entrar en subprocesos múltiples. Pero usejava.util.concurrent
estructuras de datos siempre que pueda.fuente
wait
sí, nunca lo haríasnotify
. Sin embargo, en los documentos de API paraObject.wait
"El subproceso libera la propiedad de este monitor". Entonces, mientras está dentrowait
, es como si estuviera fuera de lossynchronized
bloques circundantes (para el mismo objeto, puede haber múltiplessynchronized
bloques en el mismo objeto).Sé que este hilo tiene casi 2 años, pero aún necesito cerrar esto ya que también vine a esta sesión de preguntas y respuestas con el mismo problema ...
Lea esta definición de ilegalMonitorException una y otra vez ...
IllegalMonitorException se genera 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 poseer el monitor especificado.
Esta línea una y otra vez dice, IllegalMonitorException llega cuando ocurre una de las 2 situaciones ...
1> espera en el monitor de un objeto sin tener el monitor especificado.
2> notifique a otros hilos que esperan en el monitor de un objeto sin poseer el monitor especificado.
Algunos podrían haber obtenido sus respuestas ... quien no, entonces verifique 2 declaraciones ...
sincronizado (objeto)
object.wait ()
Si ambos objetos son iguales ... entonces no puede venir ninguna excepción de monitor ilegal.
Ahora lea nuevamente la definición IllegalMonitorException y no la olvidará nuevamente ...
fuente
Según sus comentarios, parece que está haciendo algo como esto:
Hay tres problemas
Como han dicho otros,
obj.wait()
solo se puede invocar si el subproceso actual contiene el bloqueo / mutex primitivo paraobj
. Si el hilo actual no mantiene el bloqueo, obtienes la excepción que estás viendo.La
thread.wait()
llamada no hace lo que parece que espera que haga. Específicamente,thread.wait()
no hace que el hilo nominado espere. Más bien hace que el hilo actual espere hasta que otro hilo llamethread.notify()
othread.notifyAll()
.En realidad, no existe una forma segura de forzar una
Thread
pausa de una instancia si no lo desea. (Lo más cercano que Java tiene a esto es el obsoletoThread.suspend()
método , pero ese método es intrínsecamente inseguro, como se explica en el Javadoc).Si desea que el recién iniciado se
Thread
detenga, la mejor manera de hacerlo es crear unaCountdownLatch
instancia y hacer que la llamada de subprocesoawait()
en el pestillo se detenga. El hilo principal luego llamaríacountDown()
al pestillo para permitir que el hilo en pausa continúe.Ortogonal a los puntos anteriores, el uso de un
Thread
objeto como bloqueo / mutex puede causar problemas. Por ejemplo, el javadoc paraThread::join
dice:fuente
Como no ha publicado el código, estamos trabajando en la oscuridad. ¿Cuáles son los detalles de la excepción?
¿Estás llamando a Thread.wait () desde dentro del hilo o fuera de él?
Pregunto esto porque de acuerdo con el javadoc para IllegalMonitorStateException, es:
Para aclarar esta respuesta, esta llamada a esperar en un hilo también arroja IllegalMonitorStateException, a pesar de ser llamado desde dentro de un bloque sincronizado:
fuente
wait()
.worker.wait()
línea? Entonces deberías estar sincronizando con el trabajador, no en la cerradura.Para tratar con IllegalMonitorStateException, debe verificar que todas las invocaciones de la espera, notificar y notificar Todos los métodos se lleven a cabo solo cuando el subproceso de llamada sea el propietario del monitor apropiado . La solución más simple es encerrar estas llamadas dentro de bloques sincronizados. El objeto de sincronización que se invocará en la declaración sincronizada es aquel cuyo monitor debe ser adquirido.
Aquí está el ejemplo simple para entender el concepto de monitor
fuente
La llamada Thread.wait () tiene sentido dentro de un código que se sincroniza en el objeto Thread.class. No creo que sea lo que quisiste decir.
Usted pregunta
Solo puede hacer que su hilo actual espere. Cualquier otro hilo solo 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 muy mala elección), es un AFAIK único, por lo que sincronizarlo (excepto los métodos estáticos de Thread) es peligroso.
Tom Hawtin ya explica los detalles de sincronización y espera.
java.lang.IllegalMonitorStateException
significa que está intentando esperar en un objeto en el que no está sincronizado; es ilegal hacerlo.fuente
No estoy seguro de si esto ayudará a alguien más o no, pero esta fue la parte clave para solucionar mi problema en la respuesta anterior del usuario "Tom Hawtin - tacklin":
Solo el hecho de que el "bloqueo" se pasa como un argumento en sincronizado () y también se usa en "bloqueo" .notifyAll ();
Una vez que lo logré en esos 2 lugares, lo conseguí funcionando
fuente
Recibí un
IllegalMonitorStateException
tiempo tratando de despertar un hilo en / desde unclass
hilo diferente . Enjava 8
puede utilizar laslock
características de la nueva API de concurrencia en lugar desynchronized
funciones.Ya estaba almacenando objetos para
asynchronous
transacciones websocket en aWeakHashMap
. La solución en mi caso fue también almacenar unlock
objeto en unConcurrentHashMap
parasynchronous
respuestas. Tenga en cuenta elcondition.await
(no.wait
).Para manejar el subprocesamiento múltiple, utilicé a
Executors.newCachedThreadPool()
para crear un grupo de subprocesos .fuente
Aquellos que usan Java 7.0 o una versión inferior pueden consultar el código que usé aquí y funciona.
fuente