Is there a way to tell, for a Java object, which Thread (or null) currently owns its monitor? Or at least a way to tell if the current thread owns it?
-
1You can do a thread dump to get this information – fge Jun 20 '13 at 07:02
4 Answers
I've found out some answers myself. To test if the current thread holds the monitor, Thread.holdsLock
exists!
if (!Thread.holdsLock(data)) {
throw new RuntimeException(); // complain
}
This is really fast (sub-microsecond) and has been available since 1.4.
To test in general, which thread (or thread ID) holds the lock, it's possible to do this with java.lang.management
classes (thanks @amicngh).
public static long getMonitorOwner(Object obj) {
if (Thread.holdsLock(obj)) return Thread.currentThread().getId();
for (java.lang.management.ThreadInfo ti :
java.lang.management.ManagementFactory.getThreadMXBean()
.dumpAllThreads(true, false)) {
for (java.lang.management.MonitorInfo mi : ti.getLockedMonitors()) {
if (mi.getIdentityHashCode() == System.identityHashCode(obj)) {
return ti.getThreadId();
}
}
}
return 0;
}
There's a few caveats with this:
- It's a little slow (~½ millisecond in my case and presumably increases linearly with the number of threads).
- It requires Java 1.6, and a VM for which
ThreadMXBean.isObjectMonitorUsageSupported()
is true, so it's less portable. - It requires the "monitor" security permission so presumably wouldn't work from a sandboxed applet.
- Turning the thread ID into a Thread object, if you need to, is a bit non-trivial, as I imagine you'd have to use Thread.enumerate and then loop through to find out which one has the ID, but this has theoretical race conditions because by the time you call enumerate, that thread might not exist any more, or a new thread might have appeared which has the same ID.
But if you only want to test the current thread, Thread.holdsLock
works great! Otherwise, implementations of java.util.concurrent.locks.Lock
may provide more information and flexibility than ordinary Java monitors (thanks @user1252434).

- 48,794
- 16
- 117
- 146
The java classes monitor is internal to the JVM and you cannot really play with it.
If you know that the object is locked, you can try to obtain the monitor again - if you can get it, it means that you're locking the object from your thread (because java locks are recursive - you can lock twice from the same thread). The problem is that you cannot try to synchronize.
You can use the unsafe object to do that.
unsafe has a tryMonintorEnter()
method that does just that. see unsafe.
Unsafe might be able to actually help you get the thread that holds the monitor, but I don't know how to do that...

- 833
- 1
- 8
- 13
Instead of using synchronized
, you might want to take a look at ReentrantLock, especially its methods getOwner()
and isHeldByCurrentThread()
. It takes a bit more discipline to use, though, since you explicitly have to unlock()
it, preferrably in a finally
block.

- 2,083
- 1
- 15
- 21
-
I wasn't familiar with RentrantLock. Although it wasn't my question I think it's actually better for my use case, as I can do the locking in class C and maintain the lock between calls. Thanks a lot. – Boann Jun 20 '13 at 08:19
-
You can keep your locking logic, if you like. The only required change to use ReentrantLock is from `synchronized(myLock) { .. }` to `myLock.lock(); try { .. } finally {myLock.unlock();}`. Though, unlike for synchronized the lock cannot be just any Object. – user1252434 Jun 20 '13 at 08:37
In Java 1.6 you can use Reflection to get this information.
ThreadMXBean tBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfo = tBean .getThreadInfo(bean.getAllThreadIds(), true, true);

- 7,831
- 3
- 35
- 54