Search code examples
javajava.util.concurrent

unlocking a lock.tryLock with timeout


I have this code

Lock lock = new ReentrantLock();

void someMethod() {
    try {
        if (lock.tryLock(120, TimeUnit.SECONDS)) {
            // do stuff
        } else {
            // timed out 
            throw new RuntimeException("timeout");
        }
    } finally {
        lock.unlock();
    }
}

This works fine except when when it times out. Since the thread that timesout does not own the lock, IllegalMonitorStateException is thrown. There is no isHeldByCurrentThread in Lock interface. If I dont want to cast to ReentrantLock, I have to use something ugly

...
} finally {
    if (lock.tryLock()) {
        lock.unlock();
        lock.unlock(); // twice because tryLock is called twice
    }
}

or

...
} finally {
    if ( !timeout ) {
        lock.unlock();
    }
}

Any better options ? Thanks


Solution

  • Only unlock if you acquired the lock:

    if (lock.tryLock(120, TimeUnit.SECONDS)) {
      try {
        // Do stuff.
      } finally {
        lock.unlock();
      }
    }
    

    Note that:

    • There is an example like this in the Javadoc;
    • This idiom doesn't have anything to do with using the timeout: you would not want to unlock the lock of a call to lock() were interrupted. You should always acquire the lock outside, but immediately before, the try.