Understanding the lock area

From this I understand: "Since the calls to the lock () and unlock () methods are explicit, we can move them anywhere, setting any blocking area, from one line of code to an area that spans several methods"

So, what I understand from the above statement,

public class Test { Lock l = new ReentrantLock(); void myMethod1() { l.lock(); // Do my stuff here } void myMethod2() { // Do more stuff here l.unlock(); } } 

So, basically, I can call method1 and method2 sequentially and assume that the call is thread safe.

I am not sure if this is true, as stated above.

What if someone just calls method2 when I am already executing a pair of method1 / method2? Doesn't that complicate the situation?

I think that a lock must be obtained and released in the function itself before the control is returned from the function. Do I understand correctly?

+7
java multithreading reentrantlock
source share
3 answers

The answer to the first question:

What if someone just calls method2 when I am already running method1 / method2 pair? Doesn't that complicate the situation?

Suppose another thread calls the unlock() method of a ReentrantLock object , then an IllegalMonitorStateException will be IllegalMonitorStateException . Since the thread does not get a lock, and when it tries to unlock, then it gets an exception.
This will not affect the execution or blocking of the first thread that receives the block.

  • Same thread:

    • Lock: if the same thread that receives the lock tries to get the lock again and then locks the counter.
    • Unlock: if the same thread that receives the lock tries to unlock, then the counter lock is reduced, and as soon as the lock counter becomes 0, the thread releases the lock.
  • Miscellanea:

    • Lock: if the lock is held by another thread, the current thread is disabled for thread scheduling and is at rest until the lock is received, at which time the lock lock value will be set to one.
    • Unlock: if another thread tries to unlock when it does NOT hold the lock, then an IllegalMonitorStateException is thrown.

That is why locking and unlocking ReentrantLock requires that you have a try-catch or throw mechanism, because it throws an exception.

Read below excerpt from ReentrantLock#unlock()

If the current thread holds this lock, then the hold count is reduced. If the hold counter is zero, then the lock is released. If the current thread is not the holder of this lock, then {@link IllegalMonitorStateException} is selected .

The answer to the second question:

I think that the lock should be received and released in the function itself, before the control returns from the function. I get it right?

To use the full purpose of ReentrantLock , you can extend the locking mechanism to other methods that you cannot do with synchronized blocks and methods. See Below ReentrantLock

Mutual repeated exclusion Lock with the same basic behavior and semantics, since access to the implicit monitor lock is performed using synchronized methods and operators , but with advanced features .

+5
source share

What if someone just calls method2 when I am already executing a pair of method1 / method2? Doesn't that complicate the situation?

java.util.concurrent.locks.Lock is a more powerful mechanism than synchronized . Power tools are dangerous. Use them with caution.

See @hagrawal answer for more details.

+3
source share

Instead, consider this example:

 public class Test { ... public void method1() { l.lock(); ... } public void method2() { l.lock(); ... while (l.isHeldByCurrentThread()) { l.unlock(); } } } 

This setting means that after Thread A calls method1() , Thread B will block when any of the methods is called until Thread A calls method2() . Thus, the lock area spans zero or more calls to method1() , followed by one call to method2() .

Although in practice I would find it much easier and cleaner to write code that limits the blocking area to one method or part of a method.

+1
source share

All Articles