In Java, a thread always exists in any one of the following states. These states are:
- New
- Active
- Blocked / Waiting
- Time Waiting
- Terminated
Explanation Of Different Thread States
New: Whenever we create a new thread, it is always in a new state. For a thread in the new state, the code has not been run yet and thus has not begun its execution.
Active: When a thread invokes the start() method, it moves from the new state to the active state. The active state contains two states within it:
- Runnable
- Running
- Runnable: A thread that is ready to run is then moved to the runnable state. In the runnable state, the thread may be running or may be ready to run at any given instant of time.
- Running: When the thread gets the CPU, it moves from runnable state to the running state. Generally, the most common change in the state of a thread is from runnable to running and again back to runnable.
Blocked or Waiting: Whenever a thread is inactive for a span of time then, either the thread is in the blocked state or is in the waiting state.
Timed Waiting: A thread (its name is A) has entered the critical section of a code and is not willing to leave that critical section. In such a scenario, another thread (its name is B) has to wait forever. We can avoid such a scenario, by introducing a timed waiting state to thread B. Thus, the thread lies in the waiting state for a specific span of time, and not forever.
Terminated: A thread reaches the termination state because of the following reasons:
- When a thread has finished its job, then it exists or terminates normally.
- Abnormal termination: It occurs when some unusual events such as an handled exception or segmentation fault.
A terminated thread means the thread is no more in the system, the thread is dead, and there is no way to respawn the dead thread.
The following diagram shows the different states involved in the life cycle of a thread:

Implementation of Thread States
public static final Thread.State NEW
public static Thread.State. RUNNABLE
public static final Thread.State BLOCKED
public static final Thread.State WAITING
JAVA Executor Framework
It provides its own multi-threading framework called the Java Executor Framework. The executor framework (java.util.concurrent.Executor), released with the JDK 5 is used to run the Runnable objects without creating new threads every time and mostly re-using the already created threads. The java.util.concurrent.Executor provides factory methods that are being used to create ThreadPools of worker threads. Thread pools overcome this issue by keeping the threads alive and reusing the threads.
Types of Java Executors are:
- SingleThreadExecutor
- FixedThreadPool
- CachedThreadPool
- ScheduledExecutor
Syntax of the above executors:
ExecutorService executor = Executors.newSingleThreadExecutor();
ExecutorService fixedPool = Executors.newFixedThreadPool(2);
ExecutorService executorService = Executors.newCachedThreadPool();
ScheduledExecutorService scheduledExecService = Executors.newScheduledThreadPool(1);
cheduledExecService.scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
scheduledExecService.scheduleWithFixedDelay(Runnable command, long initialDelay, long period, TimeUnit unit)
JAVA Callable
It represents an asynchronous task that can be executed by a separate thread. For instance, it is possible to submit a Callable object to a Java Executor Service which will then execute asynchronously. The Java Callable
interface is quite simple. It contains a single method named call (). Here is how the Callable interface looks
public interface Callable<V> {
V call() throws Exception;
}
The
call () the method is called in order to execute the asynchronous task. The call() method can return a result. The call () method can also throw an Exception in case the task fails during execution.
Implementing Callable
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return String.valueOf(System.currentTimeMillis());
}
}
JAVA Program for Demonstrating Thread States
class thread implements Runnable {
public void run()
{
// moving thread2 to timed waiting state
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
"State of thread1 while it called join() method on thread2 -"
+ Test.thread1.getState());
try {
Thread.sleep(200);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Test implements Runnable {
public static Thread thread1;
public static Test obj;
public static void main(String[] args)
{
obj = new Test();
thread1 = new Thread(obj);
// thread1 created and is currently in the NEW state
System.out.println(
"State of thread1 after creating it - "
+ thread1.getState());
thread1.start();
// thread1 moved to Runnable state
System.out.println(
"State of thread1 after calling .start() method on it - "
+ thread1.getState());
}
public void run()
{
thread myThread = new thread();
Thread thread2 = new Thread(myThread);
// thread1 created and is currently in the NEW state
System.out.println(
"State of thread2 after creating it - "
+ thread2.getState());
thread2.start();
// thread2 moved to Runnable state
System.out.println(
"State of thread2 after calling .start() method on it - "
+ thread2.getState());
// moving thread1 to timed waiting state
try {
// moving thread1 to timed waiting state
Thread.sleep(200);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
"State of thread2 after calling .sleep() method on it - "
+ thread2.getState());
try {
// waiting for thread2 to die
thread2.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
"State of thread2 when it has finished it's execution - "
+ thread2.getState());
}
}
OUTPUT

Refrences
https://www.geeksforgeeks.org/lifecycle-and-states-of-a-thread-in-java/
Good one lot of information is here, good work Utkarsh.