1. Introduction
In this tutorial, We will see what is the life cycle of a Thread and what are the states involved in it. Typically, A thread can enter into any state by calling certain methods of thread. But, We can not see the thread state a particular time and but java builtin api has support to see the current status of running thread using getState() method.
In the previous article, we have seen the Thread concept of Thread Priorities.
2. List of Thread Life Cycle Status
A java thread can be in any of the following thread states during its life cycle i.e. New, Runnable, Blocked, Waiting, Timed Waiting or Terminated. These are also called life cycle events of a thread in java.
NEW: The Thread has been created but it hasn't started its execution yet
RUNNABLE: The Thread is running in the Java Virtual Machine. This is a combination of Ready + Running steps in the section 4 block diagram.
BLOCKED: The Thread is waiting for a lock
WAITING: The Thread is waiting for the action of another thread
TIME_WAITING: The Thread is waiting for the action of another thread but has a time limit
TERMINATED: The Thread has finished its execution
3. Java API Internal code
The below code is from dk.internal.misc.VM.java which is used to get the current status of Thread using int value. Thread status is indicated as an int in the Thread class. Thread.State is an enum in Thread class.
public static Thread.State toThreadState(int threadStatus) {
if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
return RUNNABLE;
} else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
return BLOCKED;
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {
return WAITING;
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {
return TIMED_WAITING;
} else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {
return TERMINATED;
} else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {
return NEW;
} else {
return RUNNABLE;
}
}
4. Explanation on Life Cycle
Let us take a look at the following thread life cycle diagram. This will gives a clear picture of each status.
Before going to main concept, Understand all these statuses are handled by the JVM and not by the underlying operating system. Underlying OS is not aware of the status of the thread.
4.1 NEW
"New" is the first status in the thread life cycle and must start with this. As soon as Thread is created in any of two ways then it immediately enters into a NEW state and It will be in the state untill the start() method is invoked. Now, at the moment thread internal state is NEW.
Thread t1 = new Thread();
4.2 RUNNABLE
To make the thread to run the main job, we need to call the start() method of thread. After invoking the start(), it enters into the RUNNABLE state. Now, this thread is passed to the Thread Scheduler which will decide whether CPU should be assigned to a thread or not. First, it will check any other high priority threads are available. If high priority thread is present then it will put the current thread execution in a WAIT state.
In most of the operating system, every thread is allocated for a small amount of processor time to perform thread actual task. This is called as Quantum or Timesilce.
t1.start();
After successful completion of the run() method execution, the thread enters into the Terminated State(DEAD).
4.3 BLOCKED
A RUNNABLE thread transitions to the BLOCKED state when it attempts to perform a task that cannot be completed immediately and it must temporarily wait until that task completes.
A blocked thread cannot use a processor, even if it is available.
4.4 WAITING
A thread can be moved to WAITING state in various scenarios. Most of the cases are calling wait() method. If any method or block of code synchronized then current thread enters into WAITING state if synchronized block is being executed by the other thread.
If the thread is coming out of WAITING state then it's again is back to the RUNNABLE state and given to the thread scheduler. Once the processor is allocated then it will call run() method.
4.5 TIMED_WAITING
At any time a Runnable thread can be moved to TIMED_WAITING if it provides an optional wait interval when it’s waiting for another thread to perform a task. We can place a java thread in TIMED WAITING state by calling it’s sleep(long millis) method or wait(long millis) method.
Such types of threads are either notified by the other threads or time elapses.
Note: Timed waiting threads and waiting threads cannot use a processor, even if one is available.
4.6 TERMINATED
This is called DEAD status as well. After executing run() method without any problems or killing the thread makes it enter into the TERMINATED state.
5. Java Thread Life Cycle Example Program
Let us create a java program to see all of these statuses.
package com.java.w3schools.blog.java.program.to.threads;
public class ThreadLifeCycle implements Runnable {
public static Thread thread1;
public static ThreadLifeCycle threadLifeCycle;
public static void main(String[] args) {
threadLifeCycle = new ThreadLifeCycle();
thread1 = new Thread(threadLifeCycle);
// 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() {
MyCustomThread customThread = new MyCustomThread();
Thread thread2 = new Thread(customThread);
// 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());
}
}
class MyCustomThread implements Runnable {
public void run() {
// moving thread2 to timed waiting state
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
"State of thread1 while it called join() method on thread2 -" + ThreadLifeCycle.thread1.getState());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Output:
State of thread1 after creating it - NEW
State of thread1 after calling start() method on it - RUNNABLE
State of thread2 after creating it - NEW
State of thread2 after calling start() method on it - RUNNABLE
State of thread2 after calling sleep() method on it - TIMED_WAITING
State of thread1 while it called join() method on thread2 -WAITING
State of thread2 when it has finished it's execution - TERMINATED
6. Conclusion
In this article, We have seen the steps to understand the Thread Life Cycle Status and example program to see all its status at a time.
0 Comments