Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.Thread - where does threadStatus come from?

Tags:

java

By Java source code we have that

// variable not written or updated anywhere on this class
private volatile int threadStatus = 0;

public State getState() {
    // get current thread state
    return sun.misc.VM.toThreadState(threadStatus);
}

How and where is threadStatus updated?

The idea would be to eventually try to weave around updating methods with AOP and have a callback on threadStatus changes.

like image 265
Frankie Avatar asked Nov 21 '18 06:11

Frankie


2 Answers

In OpenJDK source code in file hotspot/src/share/vm/classfile/javaClasses.cpp you can see following code:

// Write the thread status value to threadStatus field in java.lang.Thread java class.
void java_lang_Thread::set_thread_status(oop java_thread,
                                         java_lang_Thread::ThreadStatus status) {
  // The threadStatus is only present starting in 1.5
  if (_thread_status_offset > 0) {
    java_thread->int_field_put(_thread_status_offset, status);
  }
}

It looks like state is managed in native code. It means that you can't intercept its change from java code.

like image 126
talex Avatar answered Oct 28 '22 12:10

talex


This is an internal thread status that should reflect Thread State as NEW, RUNNABLE,..

I found a Netbeans issue that suggest that toThreadState() is/can be implemented outside JDK code:

bugfix #262633, toThreadState() implemented locally, do not rely on JDK

So possibly also modifying threadStatus not updated in Java code, Notice 0 value stand for NEW thread status:

/** taken from sun.misc.VM
 * 
 * Returns Thread.State for the given threadStatus
 */
private static Thread.State toThreadState(int threadStatus) {
    if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
        return State.RUNNABLE;
    } else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
        return State.BLOCKED;
    } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {
        return State.WAITING;
    } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {
        return State.TIMED_WAITING;
    } else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {
        return State.TERMINATED;
    } else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {
        return State.NEW;
    } else {
        return State.RUNNABLE;
    }
}
like image 43
user7294900 Avatar answered Oct 28 '22 11:10

user7294900