Fundamentals 13 min read

Unveiling Java Thread Mechanics: From JVM States to Native Startup

This article explains how Java threads map to OS kernel threads, details the Thread.State lifecycle, shows how to create threads by extending Thread or implementing Runnable, and walks through the JNI mechanism and HotSpot source code that drives thread startup and execution.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Unveiling Java Thread Mechanics: From JVM States to Native Startup

Basic Concepts

Java threads are mapped to operating‑system kernel threads, so the JVM relies on the OS to manage them. In Linux, threads and processes share the same internal structure; a process has its own address space while threads within the same process share resources.

Simple note: this article is based on OpenJDK 1.8.

Thread States

Each state transition and the corresponding method are illustrated in the diagram below. The

Thread.State

enum defines the following states:

<code>public enum State {<br/>    // New, not yet started<br/>    NEW,<br/><br/>    // Runnable, may be waiting for OS resources<br/>    RUNNABLE,<br/><br/>    // Blocked, waiting for a monitor lock<br/>    BLOCKED,<br/><br/>    // Waiting for another thread to perform a specific action<br/>    WAITING,<br/><br/>    // Timed waiting, can set a maximum wait time<br/>    TIMED_WAITING,<br/><br/>    // Terminated<br/>    TERMINATED;<br/>}</code>

Thread Creation

Extend the Thread class:

<code>class PrimeThread extends Thread {<br/>    long minPrime;<br/>    PrimeThread(long minPrime) { this.minPrime = minPrime; }<br/><br/>    public void run() {<br/>        // compute primes larger than minPrime<br/>        ...<br/>    }<br/>}<br/><br/>PrimeThread p = new PrimeThread(143);<br/>p.start();</code>

Implement the Runnable interface (generally recommended):

<code>class PrimeRun implements Runnable {<br/>    long minPrime;<br/>    PrimeRun(long minPrime) { this.minPrime = minPrime; }<br/><br/>    public void run() {<br/>        // compute primes larger than minPrime<br/>        ...<br/>    }<br/>}<br/><br/>PrimeRun p = new PrimeRun(143);<br/>new Thread(p).start();</code>

HotSpot Source Code

JNI Mechanism

JNI (Java Native Interface) provides a set of APIs that enable Java to communicate with native languages such as C and C++. It is useful for reusing existing C libraries, interacting with hardware or the operating system, and improving performance, but it introduces two major drawbacks:

Platform dependence – native code must be compiled for each target OS.

Safety concerns – misuse can crash the JVM; native methods should be confined to a few classes to reduce coupling.

Typical usage scenario: when a legacy C library needs to be accessed from Java without rewriting it in pure Java.

Startup Process

The thread startup flow is illustrated below.

Thread Startup

After a

Thread

instance is created, calling

start()

triggers the native method

start0()

, which registers native methods and creates an OS thread.

<code>public synchronized void start() {<br/>    // Check thread state<br/>    if (threadStatus != 0) throw new IllegalThreadStateException();<br/><br/>    // Add to thread group<br/>    group.add(this);<br/><br/>    boolean started = false;<br/>    try {<br/>        // Start the native thread<br/>        start0();<br/>        started = true;<br/>    } finally {<br/>        try {<br/>            if (!started) {<br/>                group.threadStartFailed(this);<br/>            }<br/>        } catch (Throwable ignore) { /* ignore */ }<br/>    }<br/>}<br/><br/>private native void start0();</code>

The native

start0()

method is defined in HotSpot as

Java_java_lang_Thread_start0

:

<code>JNIEXPORT void JNICALL Java_java_lang_Thread_start0(JNIEnv *, jobject);</code>

During JVM initialization,

Thread.registerNatives()

registers this and other native methods:

<code>static JNINativeMethod methods[] = {<br/>    {"start0",           "()V",   (void *)&amp;JVM_StartThread},<br/>    {"stop0",            "()V",   (void *)&amp;JVM_StopThread},<br/>    // ... other native methods ...<br/>};<br/><br/>JNIEXPORT void JNICALL Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls) {<br/>    env->RegisterNatives(cls, methods, ARRAY_LENGTH(methods));<br/>}</code>
JVM_StartThread

(implemented in

src/share/vm/prims/jvm.cpp

) creates a

JavaThread

object, allocates a native OS thread via

os::create_thread

, and finally calls

Thread::start

to mark the thread as runnable.

<code>JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))<br/>    JavaThread *native_thread = NULL;<br/>    // ... create JavaThread and OS thread ...<br/>    Thread::start(native_thread);<br/>JVM_END</code>

The

JavaThread

constructor invokes

os::create_thread

, which on Linux uses

pthread_create

to launch the native thread:

<code>bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {<br/>    OSThread* osthread = new OSThread(NULL, NULL);<br/>    thread->set_osthread(osthread);<br/>    pthread_t tid;<br/>    int ret = pthread_create(&tid, &attr, (void*(*)(void*)) java_start, thread);<br/>    return true;<br/>}</code>

The entry point

java_start

simply calls the Java thread’s

run()

method:

<code>static void* java_start(Thread* thread) {<br/>    thread->run();<br/>    return 0;<br/>}</code>

Inside the HotSpot VM,

JavaThread::run()

eventually invokes

thread_main_inner

, which calls the user‑provided entry point (the

run()

method of the target

Runnable

or the overridden

Thread.run()

).

<code>void JavaThread::thread_main_inner() {<br/>    if (!this->has_pending_exception() && !java_lang_Thread::is_stillborn(this->threadObj())) {<br/>        this->entry_point()(this, this);<br/>    }<br/>    // cleanup and exit<br/>    this->exit(false);<br/>    delete this;<br/>}</code>

The Java

Thread.run()

implementation simply delegates to the associated

Runnable

if present:

<code>public void run() {<br/>    if (target != null) {<br/>        target.run();<br/>    }<br/>}</code>

References

https://www.jb51.net/article/216231.htm

https://blog.csdn.net/u013928208/article/details/108051796

https://www.cnblogs.com/whhjava/p/9916626.html

https://www.runoob.com/w3cnote/jni-getting-started-tutorials.html

https://developer.51cto.com/art/202011/632936.htm

https://blog.csdn.net/weixin_34384681/article/details/90660510

https://blog.csdn.net/weixin_30267697/article/details/95994035

https://zhuanlan.zhihu.com/p/33830504

JavaJVMConcurrencyThreadHotSpotJNI
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.