I myself found the answers. To check if the current thread supports the monitor, Thread.holdsLock exists!
if (!Thread.holdsLock(data)) { throw new RuntimeException();
It is very fast (sub microsecond) and is available since 1.4.
To check in general which thread (or thread ID) contains a lock, you can do this using the 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; }
Here are a few caveats:
- This is a bit slow (~ ½ milliseconds in my case and supposedly increases linearly with the number of threads).
- This requires Java 1.6, and a VM for which
ThreadMXBean.isObjectMonitorUsageSupported() true, so it is less portable. - This requires a “monitor” security permission, which supposedly will not work from an isolated applet.
- Rotating the thread id into a Thread object is a little nontrivial if you need to, as I suppose you have to use Thread.enumerate and then scroll to find out which one has an ID, but this has theoretical race conditions, because the time you call enumerate, this thread may no longer exist, or a new thread may appear that has the same ID.
But if you want to test the current thread, Thread.holdsLock works great! Otherwise, the java.util.concurrent.locks.Lock implementation can provide more information and flexibility than regular Java monitors (thanks @ user1252434).
Boann
source share