Determine which stream belongs to the monitor

Is there a way to tell, for a Java object, which Thread (or null) now belongs to its monitor? Or at least a way to find out if the current thread owns?

+7
source share
4 answers

I myself found the answers. To check if the current thread supports the monitor, Thread.holdsLock exists!

 if (!Thread.holdsLock(data)) { throw new RuntimeException(); // complain } 

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).

+9
source

The java class monitor is internal to the JVM, and you cannot play with it.

If you know that the object is locked, you can try to get the monitor again - if you receive it, it means that you are blocking the object from your thread (since Java locks are recursive - you can block twice from the same thread). The problem is that you cannot try to sync.

You can use an unsafe object for this. unsafe has a tryMonintorEnter() method that does just that. see unsafe .

Unsafe can help you get the stream that the monitor holds, but I don’t know how to do this ...

+2
source

In Java 1.6, you can use Reflection to get this information.

 ThreadMXBean tBean = ManagementFactory.getThreadMXBean(); ThreadInfo[] threadInfo = tBean .getThreadInfo(bean.getAllThreadIds(), true, true); 
+1
source

Instead of using synchronized you can look at ReentrantLock , especially its getOwner() and isHeldByCurrentThread() methods. However, a bit more discipline is required, as you obviously should have unlock() it, preferably in the finally block.

+1
source

All Articles