Hi Doug, David,

I'm not aware of any CRs related to the performance of Thread.getState(). Like Alan said, the implementation hasn't been changed since JDK 5 release. Probably the existing usage of Thread.getState() is not as performance sensitive as the starvation detector requires and thus the performance issue hasn't been noticed.

David Holmes wrote:
Hi Doug,

Doug Lea said the following on 07/11/10 21:20:
Also, while I'm at it, field Thread.threadStatus is suspiciously not
declared volatile.

Agreed - technically this should be a volatile field. In practice I think it only means that the window in which a stale value might be seen is slightly longer. If threadStatus were exported directly it might be more of an issue, but as an internal detail of getState() it is not likely to be.

Can you use Unsafe to grab the field directly, or would the reflection make it too slow?


That's what I'm currently doing as a sleazy workaround.
The sleaziness is not the Unsafe, which is basically fine
since this is planned for JDK code, but having to guess at startup
that the first value I get must be the one associated with RUNNABLE.

I thought this would be fairly simple but looking deeper into this it is a lot more complicated than I thought. There is a three-level mapping from:

OS/VM thread state -> VM ThreadStatus -> java.lang.ThreadState

and it is a M:N:1 mapping


This is complicated than it needed to.

I vaguely remember that the current implementation considered the compatibility issue between different version of hotspot VM and JDK (e.g. older VM running on a newer JDK with a new Thread.State enum). Also, the java_lang_Thread::ThreadStatus in hotspot was defined as ordinal values that we wanted to avoid those values hardcoded in both hotspot and jdk. Later it was changed to a hierarchical thread state represented as a bit vector (4980307) that we should have revised the implementation to map the bit vector directly to Thread.State enum but clearly the change in jdk was not done.

At least a startup you should be able to get the current thread's threadStatus and know that it represents RUNNABLE.

In addition I suspect the lazy initialization may be more necessary than I thought given the time at which this initialization might occur during the VM initialization sequence. I'd have to experiment (once I've remembered how to build regular SE Hotspot and the OpenJDK libs :) )

Some input from the original implementors would be useful (Martin? Mandy? ...)


Looking at the hotspot implementation (src/share/vm/classfile/javaClasses.hpp), java_lang_Thread::ThreadStatus is defined as a bit vector of JVMTI thread state flags: http://download.java.net/jdk7/docs/platform/jvmti/jvmti.html#GetThreadState

I think making Thread.threadStatus a volatile field and using JVMTI_JAVA_LANG_THREAD_STATE_MASK to convert Thread.threadStatus to Thread.State enum would be a good solution.

That all said, you are the best person to evaluate the performance impact of any changes so it might be best if you are the one to do the initial experiments - using a simple volatile + DCL for the init as a first attempt perhaps.


It'd be great if Doug can do the experiment and evaluate the performance impact. If you want me to prototype the jdk change, let me know and I should be able to make some time to do it next week.

Mandy

David


-Doug


Reply via email to