Fundamentals 12 min read

What Does Java’s RUNNABLE State Really Mean? A Deep Dive into Thread States

This article explains the distinction between Java's RUNNABLE thread state and the operating‑system concepts of ready, running, and waiting, covering JVM‑level definitions, I/O blocking behavior, time‑slice scheduling, and includes concrete code examples to illustrate how blocked I/O still appears as RUNNABLE.

Programmer DD
Programmer DD
Programmer DD
What Does Java’s RUNNABLE State Really Mean? A Deep Dive into Thread States

What is RUNNABLE?

The Javadoc defines RUNNABLE as a thread that is executing in the Java virtual machine.

A thread executing in the Java virtual machine is in this state.

Traditional OS thread states are usually divided as shown below:

Difference from the traditional READY state

According to the Javadoc, a thread in the RUNNABLE state is executing in the JVM but it may be waiting for other OS resources such as the processor.

A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

Thus RUNNABLE actually includes the READY state.

Difference from the traditional RUNNING state

Java thread states do not have a separate RUNNING state; the RUNNABLE state already covers it.

Modern OSes use time‑slice (time quantum) pre‑emptive round‑robin scheduling. A thread may run for 10‑20 ms (the RUNNING period) before being pre‑empted and placed back into the READY queue.

Context switches save the thread’s execution state to memory for later resumption.

When I/O is blocked

Traditional blocking I/O makes the CPU wait, but the thread is moved to a waiting queue (the WAITING state in the diagram).

When the I/O completes, an interrupt notifies the CPU, the blocked thread is interrupted, returns to the READY queue, and may be scheduled again.

Code examples

@Test
public void testInBlockedIOState() throws InterruptedException {
    Scanner in = new Scanner(System.in);
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                String input = in.nextLine();
                System.out.println(input);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(in);
            }
        }
    }, "输入输出");
    t.start();
    Thread.sleep(100);
    // state should be RUNNABLE
    assertThat(t.getState()).isEqualTo(Thread.State.RUNNABLE);
}

Running this test shows the thread remains in RUNNABLE even during a blocking read.

@Test
public void testBlockedSocketState() throws Exception {
    Thread serverThread = new Thread(new Runnable() {
        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(10086);
                while (true) {
                    // blocking accept()
                    Socket socket = serverSocket.accept();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); }
            }
        }
    }, "socket线程");
    serverThread.start();
    Thread.sleep(500);
    // state should be RUNNABLE
    assertThat(serverThread.getState()).isEqualTo(Thread.State.RUNNABLE);
}

Similarly, a thread blocked on ServerSocket.accept() is reported as RUNNABLE.

How to view the RUNNABLE state

There are two layers: the JVM layer and the underlying OS layer. The JVM maps OS threads to Java threads but only cares about the JVM‑level state.

The JVM treats a thread as still executing even if the OS thread is blocked, because the JVM’s notion of execution includes waiting for any resource.

Mapping of Java thread states

RUNNABLE corresponds to the traditional READY, RUNNING, and part of the WAITING states.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JVMI/OThreadRunnableThread State
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

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.