Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is `hold count` value useful in Reentrant Lock?

Reentrant Lock ( https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html ) has a feature to state the strength of locking by a particular Thread which is based on the value of 'hold count'. It is initilized when a Thread aquires the lock and each time when it re-aquires the lock the value is incremented. The value is decremented each time the thread invokes the unlock method on the lock.

Single thread at a time can be the owner of the Reentrant Lock hence simple boolen flag makes mcuh sense rather than an integers count. A thread already being the owner of the lock can only re-aquire it so count seams not of much. (any) use.

What is the usefulness of hold count ? What are the use cases of it ? One such use case can be to check of the current thread is holding the lock (hold count value > 0). But there are different APIs like isHeldByCurrentThread().

like image 853
nits.kk Avatar asked Nov 24 '25 06:11

nits.kk


2 Answers

The API documentation for that method explains it :

The hold count information is typically only used for testing and debugging purposes.

So it's basically a method that can help you track down instances where your code fails to call unlock(). This is especially true for cases where you have reentrant usage of the lock.

like image 83
bowmore Avatar answered Nov 25 '25 20:11

bowmore


Suppose you have a method includes a locked block, you can call it from different place. This method should do different thing according to the lock count it holds. Then you can take use of getHoldCount.

import java.util.concurrent.locks.ReentrantLock;

public class Example {

    ReentrantLock lock = new ReentrantLock();

    void method1() {
        lock.lock();
        try {
            if (lock.getHoldCount() == 1) { 
                System.out.println("call method1 directly");
            } else if (lock.getHoldCount() == 2) {
                System.out.println("call method1 by invoking it inside method2");
            }
        } finally {
            lock.unlock();
        }
    }

    void method2() {
        lock.lock();
        try {
            method1();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        Example example = new Example();
        example.method1(); // call method1 directly
        example.method2();  // call method1 by invoking it inside method2
    }
}
like image 38
xingbin Avatar answered Nov 25 '25 21:11

xingbin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!