Why Calling start() Twice on a Java Thread Throws IllegalThreadStateException
This article explains the purpose of Java's Thread.start() method, demonstrates what happens when it is invoked twice, shows the resulting IllegalThreadStateException, and provides a detailed analysis of the start() source code to clarify the thread lifecycle.
During a Java backend interview, the candidate was asked whether a thread can be started more than once after calling start(). The discussion explores the behavior of Thread.start(), the thread states, and why a second invocation results in an exception.
1. Purpose of start()
In Java, the start() method creates a new thread and invokes the run() method. The JVM transitions the thread from the NEW state to RUNNABLE, where it awaits CPU scheduling.
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("Thread is running...");
});
System.out.println(thread.getName() + ":" + thread.getState());
thread.start();
System.out.println(thread.getName() + ":" + thread.getState());
}
}Output:
Thread-0:NEW
Thread-0:RUNNABLE
Thread is running...When a Thread instance is created, it starts in the NEW state. Calling start() moves it to RUNNABLE, awaiting execution.
Note: Although many interview guides list multiple ways to create a thread, the only actual way is new Thread().start() .
2. What Happens When start() Is Called Twice?
Consider the following code that calls start() twice:
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("Thread is running...");
});
System.out.println(thread.getName() + ":" + thread.getState());
thread.start();
System.out.println(thread.getName() + ":" + thread.getState());
thread.start(); // second call
System.out.println(thread.getName() + ":" + thread.getState());
}
}Output:
Thread-0:NEW
Thread-0:RUNNABLE
Thread is running...
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:710)
at Main.main(Main.java:12)The second call throws IllegalThreadStateException because the thread has already been started.
3. Analysis of the start() Source Code (JDK 1.8)
public synchronized void start() {
// Check thread status
if (threadStatus != 0)
throw new IllegalThreadStateException();
// Add thread to its group
group.add(this);
boolean started = false;
try {
// Native method that actually starts the thread
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
// ignore
}
}
}Key points:
Status check: threadStatus indicates the internal state. If it is not zero (meaning the thread is already started or terminated), an IllegalThreadStateException is thrown.
State transition: The native method start0() moves the thread to the RUNNABLE state, where the JVM schedules it for execution.
4. Summary
The start() method can be invoked only once per Thread instance. Attempting a second call results in an IllegalThreadStateException because a thread's lifecycle progresses unidirectionally from NEW to RUNNABLE to TERMINATED and cannot be restarted.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
