Its really a nice question, we can definitely use Thread.holdLocks(obj)
, It is really useful but there is a limitation that we can only know that whether current thread is holding lock on the passed object or not. But as per question, we want to have some mechanism so that we can find that which thread, if any, is holding lock on a given object.
As of now I can think of two below ways:
- jconsole
There is a jconsole utility present jdk's bin directory. We can get the information about the threads and their statuses(WAITING, Blocked etc.). Below is the example:
Suppose we have below class:
public class ThreadLockTest {
private int i = 11;
public static void main(String[] args) {
ThreadLockTest obj = new ThreadLockTest();
TestRunner runner = new TestRunner(obj);
Thread t1 = new Thread(runner, "t1");
Thread t2 = new Thread(runner, "t2");
t1.start();
t2.start();
}
public synchronized int getI() {
try {
System.out.println(Thread.currentThread().getName()+" starting wait");
for(;;) {
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return i;
}
public synchronized void setI(int i) {
this.i = i;
}
private static class TestRunner implements Runnable {
private ThreadLockTest obj;
private TestRunner(ThreadLockTest obj) {
this.obj = obj;
}
@Override
public void run() {
System.out.println("i: "+obj.getI());
}
}
}
Run the above program, and then open the jconsole, and connect it to your program process. Now see the below screenshots of jconsole, in my case thread "t1" is holding lock ,and thread "t2" is waiting on it. You can see the message in jconsole which is clearly showing that which thread is waiting on which lock, and which thread is owning that lock. You can even use jconsole to detect deadlocks, if any.

In below screenshot, you can see the message which is clearly showing that, thread t2 is blocked for the lock which is owned by thread t1.

- Maintain a Object-Thread Map:
Here, we can maintain a map of < Object,Thread >, where the Thread is currently holding lock on this object. This approach is not really a good approach, but as we have java API limitation as there is no API which can tell which thread is holding lock on any object. SO in this approach, what we will do is, we will have a public Map, and for an object for which we are interested to know about the thread which currently holding lock on it, everytime we enter any synchronized method, we will make an entry in the Map, and when we exit from this synchronized method, we will remove the entry from Map. Like below
public synchronized void anyMethod() {
MAP.put(this,Thread.currentThread());
.................
................
Map.remove(this);
}
I know this approach is having many many drawbacks, but if we really need to know about the thread which is holding lock on any object and we do not want to use jconsole, we can think of something like this approach. I know this approach will make the code dirty. So try to avoid it as much as you can, and just use jconsole to check the thread statuses and even for detecting deadlocks, if any.
I will strongly recommend to use jconsole, if you really need to know about which threads are blocked on which locks.