java.lang.Thread - 线程状态(threadStatus)从何而来?

8

通过 Java源代码 我们有

// 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);
}

如何以及在哪里更新threadStatus

我们的想法是最终尝试使用AOP编织更新方法,并在threadStatus更改时进行回调。


你展示的代码来自Thread.java文件吗? - Teddy
@Teddy,没错!已更新问题并附上相关链接示例。 - Frankie
2个回答

6
在OpenJDK源代码中的文件hotspot/src/share/vm/classfile/javaClasses.cpp中,您可以看到以下代码:
// 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);
  }
}

看起来状态是在本机代码中管理的。这意味着您无法从Java代码中拦截其更改。


非常有帮助。谢谢。如果您有除了不断ping Thread.getStatus()之外的其他想法来监视线程状态,请告诉我。 - Frankie
如果您想监视BLOCK状态,那么您无法做其他事情。您将如何使用此信息?也许有其他方法可以实现您的目标。 - talex
@Frankie 为了调试目的,你理论上可以尝试使用修改过的 java_lang_Thread::set_thread_status 构建自己的 OpenJDK vm,并在更新线程状态的同时调用一些回调函数。 - Hulk
@ Hulk,那看起来是一种方法。 - Frankie
@talex 我正在尝试将Java推向逻辑极限,并尝试通过创建快进时间线来进行实验。因此,程序不会以实时方式运行,而是尽可能快地模拟时间,但不依赖于用户代码的更改。我已经在AspectJ方面做得相当不错了,但在某些角落情况下,线程彼此相互依赖,这时有一个回调声明更改会很有帮助。 - Frankie

1
这是一个内部线程状态,应该反映线程状态为NEW、RUNNABLE等。
我发现了一个Netbeans 问题,建议toThreadState()可以在JDK代码之外实现:

bugfix #262633,toThreadState()在本地实现,不要依赖JDK

因此,可能还需要修改Java代码中未更新的threadStatus,请注意0值代表新线程状态
/** 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;
    }
}

谢谢!不幸的是,看起来监视该变量将是不可能的。 - Frankie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接