【问题标题】:Obtaining the thread ID for Java threads in Linux获取 Linux 中 Java 线程的线程 ID
【发布时间】:2012-06-27 10:41:51
【问题描述】:

我有一个 Java 应用程序,其中创建了一些线程(通过 new Thread())。使用 ps 我可以看到它们有不同的线程 ID(LWP 列),我想从 Java 应用程序中获取这些 ID。

在我发现的与该主题相关的大多数帖子中(例如,this one),解决方案是使用ManagementFactory.getRuntimeMXBean().getName()

但是,使用该方法会为我提供主线程的 PID(即使我从其中一个线程调用它),所以它并不能真正解决我的问题。

有什么方法可以获取应用程序创建的每个 Thread 的线程 ID?

是否可以使用 JNI 来完成它?如果我能以某种方式连接到一个可以调用syscall(__NR_gettid) 的C 函数,那可以解决我的问题。我真的不关心可移植性,所以我完全可以接受只适用于 Linux 机器的解决方案。

更新:我实际上已经通过使用 JNI 解决了我的问题。详细信息在我的回答中进行了解释。谢谢大家的建议/cmets。

【问题讨论】:

  • Java 线程可能与操作系统上的实际线程不对应。
  • @nhahtdh 我不是 100% 确定 Java 线程如何映射到 Linux 线程,但至少在我的系统中,它们具有给定的线程 ID,就像 pthread 一样。正如我所说,我并不是真的在寻找便携式解决方案。
  • @betabandido:那么,您是否尝试过实现该 JNI 功能?还是我们应该为您做这些?
  • @NiklasB。我不是要求那个。由于我不再真正习惯于编写 Java 代码,而且我从未接触过 JNI,我只是想知道它是否是一个可行的选择。如果答案是肯定的,我一定会自己去看的。
  • @betabandido:您绝对应该尝试一下。我不明白为什么这不起作用。

标签: java linux multithreading pid


【解决方案1】:

最后,我发现 JNI 方法是解决我的问题的最佳方法。作为参考,我发布了代码并为其构建说明(基于 Wikipedia 上的 example):

负责与 C 代码接口的 Java 类 (GetThreadID.java):

public class GetThreadID {
    public static native int get_tid();

    static {
        System.loadLibrary("GetThreadID");
    }
}

C文件负责获取线程ID(GetThread.c):

#include <jni.h>
#include <syscall.h>
#include "GetThreadID.h"

JNIEXPORT jint JNICALL
Java_GetThreadID_get_1tid(JNIEnv *env, jobject obj) {
    jint tid = syscall(__NR_gettid);
    return tid;
}

GetThreadID类的使用示例:

class Main {
    public static void main(String[] args) {
        int tid = GetThreadID.get_tid();
        System.out.println("TID=" + tid);
    }
}

最后,构建指令(javah 自动生成GetThreadID.h):

JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:bin/javac::")
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
javac GetThreadID.java
javah GetThreadID

gcc -I${JAVA_HOME}/include -fPIC -shared GetThreadID.c -o libGetThreadID.so
javac Main.java
java Main

【讨论】:

  • 非常好,感谢您的跟进。我怀疑这不会做太多工作:) 我认为您应该在这里接受自己的答案,因为这绝对是最好的答案。
  • 我认为这里的 gcc 指令应该是 gcc -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -fPIC -shared GetThread.c -o libGetThreadID.so now a day :D!
  • 显然,如果您省略 JAVA_HOME 部分,这将不起作用。特别是如果您已经设置了 JAVA_HOME。但是,如果您按照说明以及我的修改进行操作。
【解决方案2】:

This blog post 提供了一种从 java 线程 id 映射到 LWP id 的方法。

它的要点似乎是 NLWP id 映射到 java 线程 id。

【讨论】:

  • 我认为该博客文章谈到了手动映射线程。 OP 希望在 Java 中自动完成
  • @NiklasB:我知道。我的观点是,如果 OP 愿意将线程 id 映射到 NLWP id 而不是 LWP id,它可能可以自动完成。
  • @SeanReilly 这绝对看起来很有希望。正如你所说,它可以是自动化的。我将探索这种方式,以及 JNI(这会更直接,但我还不知道它是否会起作用)。谢谢!
  • 请不要只发布链接答案。
  • @gustavohenke:感谢您非常及时的评论。 ;-)
猜你喜欢
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
相关资源
最近更新 更多