Obtaining the thread ID for Java threads in Linux

java, linux, multithreading, pid

Solution

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 example at Wikipedia):

Java class responsible to interface to the C code (`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`):

#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 `GetThreadID` class:

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

And finally, the build instructions (`javah` automatically generates `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

Problem

I have a Java application where some threads are created (via `new Thread()`). Using `ps` I can see they have different thread IDs (LWP column) and I would like to obtain those IDs from within the Java application. 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()`. 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. Is there any way to obtain the thread ID for every single `Thread` created by an application? 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. UPDATE: I have actually solved my problem by using JNI. Details are explained in my answer. Thank you all for your suggestions/comments.

Original source

Related problems