GeeCON Prague 2014*
The moose likes Threads and Synchronization and the fly likes How Useful is ThreadInfo? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "How Useful is ThreadInfo?" Watch "How Useful is ThreadInfo?" New topic
Author

How Useful is ThreadInfo?

Saul Tocsin
Greenhorn

Joined: Feb 25, 2012
Posts: 14
Hi All,

In putting together a "state sampling" monitor (periodically wake up and inquire about the state of application threads known to the JVM), I came upon something troubling, and perhaps unavoidable.

The issue is quite simple:

a. call ThreadMXBean.getThreadInfo to populate a ThreadInfo[] for threads I find interesting (my application's threads).
b. iterate over this array calling a few of the ThreadInfo methods (e.g., getThreadId, getThreadName, getThreadState).
c. find a thread in BLOCKED state (Thread.State)
d. try to inquire further about the blocked thread, e.g., call getLockInfo

But by the time (d) fires, the thread is no longer in BLOCKED state and the call to getLockInfo returns null.

I think I need some kind of "snapshot" of the entirety of thread state. I mean something that will return a picture of the thread at a given point in time; and NOT require me to call methods that query the live thread.

Questions:

1. of what use is ThreadInfo in a situation like this?
2. is there some way of obtaining the "snapshot" I described?

Thanks, All.

-Saul

Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3610
    
  60

Are you using ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers) method (passing true as the second and third parameter)? I use this when I need to dump as detailed information as possible (basically, in my deadlock detector thread ) and was always able to pin down the problem from that.
Saul Tocsin
Greenhorn

Joined: Feb 25, 2012
Posts: 14
Hi Martin,

Thanks for the reply.

I am using not the variant of getThreadInfo that you describe. Rather, I am using

I had looked at the variant you recommend, but wasn't sure if it accomplishes what I want. If I understand the API docs correctly, using

does not give me information about what the thread is waiting on (see ThreadInfo.getLockInfo()). Rather, it shows me monitors and ownable synchronizers that are "currently locked by the thread." My goal is to try to figure exactly what a waiting thread is waiting on.

This whole issure arose as I executed this code:



I get NPEs in these calls if the target thread (represented by the ThreadInfo variable ti) has ended. So it seemed to me that the array of ThreadInfo objects returned by the call to getThreadInfo did NOT, as I had hoped, contain all of the state needed to resolve the calls inside the for loop. That is, those calls might require interrogating the thread itself. Such interrogation against a dead thread leads to the NPE.

This behavior, which can only occur at thread termination, got me thinking more generally about the relationship between the ThreadInfo object and the actual Thread instance. And it was here that the more troubling concern arose, namely that I couldn't be sure that the ThreadInfo was consistent with the current state of the thread, i.e., its state after the getThreadInfo() call completes. Specifically, if ThreadInfo.getThreadState() shows me Thread.State of BLOCKED, will a subsequent call to ThreadInfo.getLockInfo() return the LockInfo object that the thread was BLOCKED on at the time of the getThreadInfo() call; or, because the the thread is now RUNNABLE, will it return null?

Thank you for considering this matter. I find this issue troubling and would like to get to the bottom of it without having to resort to a JVMTI approach.

-Saul
Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3610
    
  60

When I call toString() on the ThreadInfo obtained the way I've described, I get this:

Do you need more detailed output?

Anyway, I've had a look at the ThreadInfo source in the JDK, and it does not seem to be accessing live threads; everything comes from fields initialized by constructors. I don't see how the state of the thread after ThreadInfo has been constructed could change any of its values...
Saul Tocsin
Greenhorn

Joined: Feb 25, 2012
Posts: 14
Martin,

That is very good news - thank you!

I will look into it more closely this afternoon.

-Saul
Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3610
    
  60

Also note that dumpAllThreads Javadoc notes that a captured thread might be gone when that method returns. However, it does not mention that it's data might be invalid at that moment.

On the other hand: unless JVM is stopped for the duration of obtaining this info (which I doubt), it seems you cannot get an internally consistent snapshot of all threads' state.
Saul Tocsin
Greenhorn

Joined: Feb 25, 2012
Posts: 14
On the other hand: unless JVM is stopped for the duration of obtaining this info (which I doubt), it seems you cannot get an internally consistent snapshot of all threads' state.


Hmm...are you saying that internal consistency of threads' states not possible via dumpAllThreads?

Do you still think we have consistency via the form of getThreadInfo that you recommended?

-Saul
Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3610
    
  60

I think the Javadoc does not clearly state anything about internal consistency, and I would consider the possibility that neither of these method creates consistent snapshot. You might be able to find more info on the internet, or prove there is inconsistency by analyzing the output (eg. a thread waiting on a lock no one else owns).

Doh! The cause of your NPEs is actually quite clear from the Javadoc:

This method returns an array of the ThreadInfo objects, each is the thread information about the thread with the same index as in the ids array. If a thread of the given ID is not alive or does not exist, null will be set in the corresponding element in the returned array. A thread is alive if it has been started and has not yet died.
Saul Tocsin
Greenhorn

Joined: Feb 25, 2012
Posts: 14
Ah, screw-up (misinterpretation) on my part.

Thanks again, Martin.

-Saul
Saul Tocsin
Greenhorn

Joined: Feb 25, 2012
Posts: 14
Follow up question for you, Martin:

In using this form



do you then follow it with a call to ThreadInfo.getStackTrace() ?

Put otherwise, where does the information you displayed come from, e.g.,

"Thread-6" Id=28 BLOCKED on java.lang.Object@1fc7b3a owned by "Thread-5" Id=27
at xxx.Tests$1Deadlock.run(Tests.java:530)
- blocked on java.lang.Object@1fc7b3a
- locked java.lang.Object@fe2509
at java.lang.Thread.run(Unknown Source)

Thanks.

-Saul

Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3610
    
  60

The output I posted earlier is produced by ThreadInfo.toString() (as I already mentioned there).
 
Don't get me started about those stupid light bulbs.
 
subject: How Useful is ThreadInfo?