Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtaining the thread ID for Java threads in Linux

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.

like image 597
betabandido Avatar asked Jun 27 '12 10:06

betabandido


People also ask

How do I find thread ID in Linux?

On Linux systems, you can get thread ID thus: #include <sys/types. h> pid_t tid = gettid();

Which method of thread give the ID of a thread?

The getId() method of Thread class returns the identifier of the invoked thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime.

Is thread ID same as pid How will you get thread ID?

In a single-threaded process, the thread ID is equal to the process ID (PID, as returned by getpid(2)). In a multithreaded process, all threads have the same PID, but each one has a unique TID.

How do I get Jstack on Linux?

TO GET THE JSTACK: Enter the following commands in the order shown, replacing: <installDir> with the path to the directory that Analyze is installed under. <processId> with the PID you got from the above. <someFileName> with the name of a file which the output of the jstack command will be written to.


2 Answers

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
like image 139
betabandido Avatar answered Oct 05 '22 17:10

betabandido


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

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

like image 41
Sean Reilly Avatar answered Oct 05 '22 17:10

Sean Reilly