获取Linux中Java线程的线程ID

时间:2012-06-27 10:41:52

标签: java linux multithreading pid

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

在我找到的与此主题相关的大多数帖子中(例如this one),解决方法是使用ManagementFactory.getRuntimeMXBean().getName()

但是,使用该方法可以获得主线程的PID(即使我从其中一个线程调用它),所以它并没有真正解决我的问题。

有没有办法获取应用程序创建的每个Thread的线程ID?

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

更新:我实际上已经使用JNI解决了我的问题。细节在我的回答中解释。谢谢大家的建议/意见。

3 个答案:

答案 0 :(得分:10)

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

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

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

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

负责获取线程ID(GetThread.c)的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

答案 1 :(得分:2)

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

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

答案 2 :(得分:-2)

如果你想要线程ID(在java中运行多个线程的Id)。从您的Java代码中,您可以调用Thread#getId()并输入所需的日志。

Thread.currentThread().getId();

要获取流程ID,您可以尝试使用此功能。SOURCE

    byte[] bo = new byte[100];
    String[] cmd = { "bash", "-c", "echo $PPID" };
    Process p=null;
    try {
        p = Runtime.getRuntime().exec(cmd);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        p.getInputStream().read(bo);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
   System.out.println(new String(bo));