7

I'm using ReentrantLock with its recommended practise (lock, then actual code in try-block, then unlock in finally, see code example below). Sometimes (very very rare) I'm having java.lang.IllegalMonitorStateException exception during unlock. Why it happens? Maybe its somehow related to Android's implementation of Java VM.

Error:

java.lang.IllegalMonitorStateException
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:126)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1232)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:430)
at com.example.dummy.backend.model.Model.unlock(Model.java:283)
at com.example.dummy.backend.engine.Engine.removeOldInstances(Engine.java:712)
at com.example.dummy.backend.engine.Engine$ProcessOnResumeWorkInBackground.doInBackground(Engine.java:836)
at com.example.dummy.backend.engine.Engine$ProcessOnResumeWorkInBackground.doInBackground(Engine.java:790)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)

Code example (slightly simplified):

myLock.lock();
try {
        LinkedList<MyClass> myClassInstances = model.getMyClassInstances();
        Iterator<MyClass> iterator = myClassInstances.iterator();
        while (iterator.hasNext()) {
                MyClass myClassInstance = iterator.next();
                boolean toBeRemoved = true; // simple condition here
                if (toBeRemoved) {
                        logger.info("Removing old myClassInstance " + myClassInstance.getTimestamp());
                        iterator.remove();
                        Cache.removeMyClassByCodeAndTimestamp(myClassInstance);
                }
        }
} finally {
        myLock.unlock();
}
nightuser
  • 664
  • 4
  • 13
  • Did you ever figure out the cause of this? – Grumblesaurus Jul 02 '19 at 02:28
  • @JoshuaD unfortunately, no. But it was so long ago that I even don't write any Java anymore for years. Do you still experience such an issue? – nightuser Jul 02 '19 at 10:58
  • Yea, for me this was happening because I had put unlock() in a finally {} and sometimes the try {} was deciding not to lock, so I would try to unlock something that hadn't been locked. I added a little flag indicating whether we locked and put an if in the finally, and problem solved. – Grumblesaurus Jul 02 '19 at 16:43
  • I'll make that an answer in a few, I'm on a mobile device at the moment. It looks like you were having the same problem. – Grumblesaurus Jul 02 '19 at 16:44
  • @JoshuaD but lock comes before the try-block. – nightuser Jul 02 '19 at 16:47

0 Answers0