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