Answer to first question:
What if somebody just calls method2 when i am already executing
method1/method2 pair? Doesn't it complicate things.
Suppose another thread calls the unlock()
method on the ReentrantLock
object then IllegalMonitorStateException
would be thrown. Because the thread is not acquiring the lock and when it tries to unlock then it get exception.
It will not have any effect on execution or locking of first thread which is acquiring the lock.
Same thread:
- Lock: If same thread which is acquiring the lock again tries to acquire the lock then lock counter increments.
- Unlock: If same thread which is acquiring the lock tries to unlock then lock counter decrements and as soon as lock counter becomes 0, thread releases the lock.
Different thread:
- Lock: If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired, at which time the lock hold count is set to one.
- Unlock: If different thread tries to
unlock
when it is NOT holding the lock then IllegalMonitorStateException is thrown.
That is the reason ReentrantLock
lock and unlock mandates you to have try-catch or throw mechanism because it throws exception.
Read below excerpt from ReentrantLock#unlock()
If the current thread is the holder of this lock then the hold
count is decremented. If the hold count is now zero then the lock is
released. If the current thread is not the holder of this lock then
{@link IllegalMonitorStateException} is thrown.
Answer to second question:
I think a lock should be acquired and released in the function itself,
before the control is returned from the function. Is my understanding
correct?
That's the whole purpose of ReentrantLock
, you can extend the locking mechanism to other methods, which you cannot do with synchronized blocks and methods. See below from ReentrantLock
A reentrant mutual exclusion Lock with the same basic behavior and
semantics as the implicit monitor lock accessed using synchronized
methods and statements, but with extended capabilities.
I think a lock should be acquired and released in the function itself, before the control is returned from the function.
It is a lot easier to do it this way but it isn't necessary with reentrantlock. – AnimalistLockMethod
andUnlockMethod
annotations then you'll get a compile time check. – Lifelong