Why may this happen? The thing is that monitor object is not null for sure, but still we get this exception quite often:
java.lang.IllegalMonitorStateException: (m=null) Failed to get monitor for (tIdx=60) at java.lang.Object.wait(Object.java:474) at ...
The code that provokes this is a simple pool solution:
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(); } } }
Am I missing something?
EDIT: The exception happens in available.wait();
line.
Class IllegalMonitorStateExceptionThrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
An IllegalMonitorStateException is a runtime exception in Java that occurs in multithreaded applications. It indicates that the calling thread has attempted to wait on an object's monitor, or attempted to notify other threads waiting on an object's monitor, without owning the specified monitor.
2. When Is It Thrown? The IllegalMonitorStateException is related to multithreading programming in Java. If we have a monitor we want to synchronize on, this exception is thrown to indicate that a thread tried to wait or to notify other threads waiting on that monitor, without owning it.
See the javadoc for Object.wait.
in particular "The current thread must own this object's monitor." and "[throws] IllegalMonitorStateException - if the current thread is not the owner of the object's monitor." That is, you need to synchronize on the object you are going to call wait on.
so your code should be:
synchronized (available) { available.wait(); }
available.wait();
must be in a synchronized(available) section
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With