在 Linux 中获取 Java 线程的线程 ID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11224394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 07:05:12  来源:igfitidea点击:

Obtaining the thread ID for Java threads in Linux

javalinuxmultithreadingpid

提问by betabandido

I have a Java application where some threads are created (via new Thread()). Using psI can see they have different thread IDs (LWP column) and I would like to obtain those IDs from within the Java application.

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

In most of the posts related to this topic that I have found (e.g., this one), the solution is to use ManagementFactory.getRuntimeMXBean().getName().

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

Using that method, however, gives me the PID of the main thread (even if I call it from one of the threads), so it is not really solving my problem.

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

Is there any way to obtain the thread ID for every single Threadcreated by an application?

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

Would it be possible to use JNI to accomplish it? If somehow I could interface to a C function where I could call syscall(__NR_gettid), that could solve my problem. I really do not care about portability, so I am totally okay with a solution that would only work for a Linux machine.

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

UPDATE:I have actually solved my problem by using JNI. Details are explained in my answer. Thank you all for your suggestions/comments.

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

采纳答案by betabandido

In the end, I found the JNI way to be the best one to solve my problem. As a reference, I post the code and build instructions for it (based on the exampleat Wikipedia):

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

Java class responsible to interface to the C code (GetThreadID.java):

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

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

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

C file responsible to obtain the thread ID (GetThread.c):

负责获取线程 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;
}

An example of how to use GetThreadIDclass:

如何使用GetThreadID类的示例:

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

And finally, the build instructions (javahautomatically generates GetThreadID.h):

最后,构建指令(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

回答by Akhi

If you want thread ids(Id of multiple threads running in the java). From your java code you can call the Thread#getId()and put in the required logs.

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

Thread.currentThread().getId();

For getting the process id you can try out this.SOURCE

要获取进程 ID,您可以试试这个。来源

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

回答by Sean Reilly

This blog postprovides a method of mapping from java thread ids to LWP ids.

这篇博文提供了一种从 java 线程 id 映射到 LWP id 的方法。

The gist of it seems to be that the NLWP id maps to the java thread id.

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