Java.lang.IllegalMonitorStateException: (m=null) No se pudo obtener el monitor para
¿Por qué puede suceder esto? La cosa es que el objeto monitor no es nulo con seguridad, pero aún así obtenemos esta excepción bastante a menudo:
java.lang.IllegalMonitorStateException: (m=null) Failed to get monitor for (tIdx=60)
at java.lang.Object.wait(Object.java:474)
at ...
El código que provoca esto es una solución de pool simple:
public Object takeObject() {
Object obj = internalTakeObject();
while (obj == null) {
try {
available.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
obj = internalTakeObject();
}
return obj;
}
private Object internalTakeObject() {
Object obj = null;
synchronized (available) {
if (available.size() > 0) {
obj = available.keySet().iterator().next();
available.remove(obj);
synchronized (taken) {
taken.put(obj, Boolean.valueOf(true));
}
}
}
return obj;
}
public void returnObject(Object obj) {
synchronized (taken) {
taken.remove(obj);
}
synchronized (available) {
if (available.size() < size) {
available.put(obj, Boolean.valueOf(true));
available.notify();
}
}
}
¿Me estoy perdiendo algo?
EDITAR : La excepción ocurre en la línea available.wait();
.
3 answers
Ver el objeto javadoc for.Esperen.
En particular "El hilo actual debe poseer el monitor de este objeto."y" [lanza] IllegalMonitorStateException-si el hilo actual no es el propietario del monitor del objeto."Es decir, necesita sincronizar en el objeto que va a llamar a wait on.
Así que su código debe ser:
synchronized (available) {
available.wait();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-12 11:03:13
available.wait();
debe estar en una sección sincronizada (disponible)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-05 12:11:40
El método TakeObject() debe estar sincronizado o, tenemos que escribir bloque sincronizado dentro de este método. Espero que u obtenga una excepción de tiempo de compilación para esto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-15 12:46:47