One to One Mapping of Java Thread to Linux Thread (Lwp)

One to one mapping of Java Thread to Linux thread (LWP)


Is there a one to one mapping between Java Thread objects and OS threads (

Yes there is, it has been since Java 1.2.

Prior to Java 1.2 a "green threads" model were used which mapped several Java threads to one OS thread.

How does the thread state of Java map to linux? If the state of Java is runnable, what is on Linux

Java documentation clearly says

A thread can be in only one state at a given point in time. These states are virtual machine states which do not reflect any operating system thread states.

There is no true mapping. You can read the docs

How to find a Java thread running on Linux with ps -axl?

Use

jps -v

for finding your java process. Sample Output:

3825 RemoteMavenServer -Djava.awt.headless=true -Xmx512m -Dfile.encoding=MacRoman
6172 AppMain -Didea.launcher.port=7533 -Didea.launcher.bin.path=/Applications/IntelliJ IDEA 10.app/bin -Dfile.encoding=UTF-8
6175 Jps -Dapplication.home=/Library/Java/JavaVirtualMachines/1.6.0_31-b04-411.jdk/Contents/Home -Xms8m

Then use

jstack 6172

(6172 is id of your process) to get stack of threads inside jvm. Thread priority could be found from it. Sample output:

.....
"main" **prio=5** tid=7ff255800800 nid=0x104bec000 waiting on condition [104beb000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at au.com.byr.Sample.main(Sample.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

.....

Enjoy!

EDIT: If application running under different user than yourself (typical case on production and other non-local environments) then jps/jstack should be run via sudo. Examples:

sudo jps -v

sudo jstack 6172

Obtaining the thread ID for Java threads in Linux

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

linux top show java threads?

It depends on your versions of various tools. Most likely, you have a version of top that doesn't understand the relationship between threads and processes on Linux, resulting in it incorrectly showing each thread as its own process. The implementation of Java threads depends on your VM, but the typical implementation on modern JVMs and Linux versions is 1-to-1, that is, each Java thread is a Linux KSE created by the clone system call.

If you have a Linux distribution that came out within the past three years, you shouldn't have this issue.

Distinguishing between Java threads and OS threads?

On Linux, Java threads are implemented with native threads, so a Java program using threads is no different from a native program using threads. A "Java thread" is just a thread belonging to a JVM process.

On a modern Linux system (one using NPTL), all threads belonging to a process have the same process ID and parent process ID, but different thread IDs. You can see these IDs by running ps -eLf. The PID column is the process ID, the PPID column is the parent process ID, and the LWP column is the thread (LightWeight Process) ID. The "main" thread has a thread ID that's the same as the process ID, and additional threads will have different thread ID values.

Older Linux systems may use the "linuxthreads" threading implementation, which is not fully POSIX-compliant, instead of NPTL. On a linuxthreads system, threads have different process IDs.

You can check whether your system is using NPTL or linuxthreads by running the system's C library (libc) as a standalone program and looking under "Available extensions" in its output. It should mention either "Native POSIX Threads Library" or linuxthreads. The path to the C library varies from system to system: it may be /lib/libc.so.6, /lib64/libc.so.6 (on 64-bit RedHat-based systems), or something like /lib/x86_64-linux-gnu/libc.so.6 (on modern Debian-based systems such as Ubuntu).

At the OS level, theads don't have names; those exist only within the JVM.

The pthread_kill() C function can be used to send a signal to a specific thread, which you could use to try to kill that specific thread from outside the JVM, but I don't know how the JVM would respond to it. It might just kill the whole JVM.



Related Topics



Leave a reply



Submit