java.lang.IllegalMonitorStateException: (m=null) F

2019-01-31 17:47发布

问题:

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.

回答1:

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();
}


回答2:

available.wait(); must be in a synchronized(available) section



回答3:

takeObject() method must be synchronized or, we have to write synchronized block inside this method. I hope u should get compile time exception for this.