views:

54

answers:

3

I'm developing for Android 2.2, and a bit confused as to how ReentrantLocks work. Can the following code ever throw an IllegalMonitorStateException? I ask because I don't see how it can--according to the API, tryLock returns true if and only if the lock is successfully obtained--but occasionally the unlock() command does.

public void lockDemo() {
    ReentrantLock myLock = new ReentrantLock();
    if (myLock.tryLock()) {
        System.out.println("Lock obtained");
        myLock.unlock();
    }
}
A: 

It might not actually solve your problem, but there's some discussion of something similar here: http://www.jroller.com/ethdsy/entry/reentrantlock_bug

Curtis
Thanks for the link. Like you said, I don't think the solution is applicable to my code, but at least now I know I'm not crazy.
SirBoss
A: 

The tryLock() mothod takes two parameters, long timeout, TimeUnit unit. That could have something to do with it.

I'm not saying that way of using locks is wrong, I've just never used them that way. I've been taught to use locks in this fashion:

public void lockDemo() {
    ReentrantLock myLock = new ReentrantLock();
    try {
        myLock.lock();
        // do work...
    } catch (Exception e) {
        // catch if something fails
    } finally {
        myLock.unlock();
    }
}
komidore64
There's also a tryLock() that doesn't take arguments--it just returns false immediately if the lock is unavailable. I haven't seen many official code samples that use it, though.http://developer.android.com/reference/java/util/concurrent/locks/ReentrantLock.html#tryLock()
SirBoss
+1  A: 

From the javadoc: unlock() throws IllegalMonitorStateException if the current thread does not hold the lock. I'm guessing you would not be asking unless you are seeing this, but, you should check the stack trace to see what method is triggering it. The example you give won't reproduce this situation, so your real code must be more complex and the problem must lie somewhere in the other bits.

Off the top of my head, I can imagine that maybe the lock is actually being unlocked twice somehow. Or that the lock may not actually be successfully acquired in some code paths that think they have the lock.

Sean Owen
I agree with your assessment, but I have absolutely no idea what other code I could possibly write that would cause this to happen. AFAIK, If another thread holds the lock, this thread can't obtain it; if this thread holds the lock, it should be able to release it. Unless I'm missing something?
SirBoss
That's right but maybe it's released twice? Maybe it's unlocked without holding the lock somehow? Those scenarios. A minute with a debugger tracking calls to methods on that lock should show it.
Sean Owen