Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
215 views
Welcome To Ask or Share your Answers For Others

1 Answer

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:

  1. It's a little slow (~? millisecond in my case and presumably increases linearly with the number of threads).
  2. It requires Java 1.6, and a VM for which ThreadMXBean.isObjectMonitorUsageSupported() is true, so it's less portable.
  3. It requires the "monitor" security permission so presumably wouldn't work from a sandboxed applet.
  4. 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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...