Back to: Java Tutorials For Beginners and Professionals
Thread Life Cycle in Java with Examples
In this article, I am going to discuss Thread Life Cycle in Java with examples. Please read our previous article where we discussed Thread Class in Java. The thread can exist in different states. Just because a thread’s start() method has been called, it doesn’t mean that the thread has access to the CPU and can start executing straight away. Several factors determine how it will process. So, at the end of this article, you will understand the life cycle of Thread in Java.
Thread Life Cycle in Java
A thread goes through various stages in its life cycle. According to Sun, there are only 4 states in the thread life cycle in java new, runnable, non-runnable, and terminated. There is no running state. But for a better understanding of the threads, we are explaining it in the 5 states. The life cycle of the thread in java is controlled by JVM.
For a better understanding please have a look at the below diagram. The java thread states are as follows:
- Newborn
- Runnable
- Running
- Blocked (Non-Runnable)
- Dead (Terminated)
Following are the stages of the life cycle –
New – A new thread begins its life cycle in the new state. It remains in this state until the program starts the thread. It is also referred to as a born thread. In simple words, a thread has been created, but it has not yet been started. A thread is started by calling its start() method.
Runnable – The thread is in the runnable state after the invocation of the start() method, but the thread scheduler has not selected it to be the running thread. A thread starts life in the Ready-to-run state by calling the start method and waiting for its turn. The thread scheduler decides which thread runs and for how long.
Running – When the thread starts executing, then the state is changed to a “running” state. The scheduler selects one thread from the thread pool, and it starts executing in the application.
Dead – This is the state when the thread is terminated. The thread is in a running state and as soon as it is completed processing it is in a “dead state”. Once a thread is in this state, the thread cannot even run again.
Blocked (Non-runnable state):
This is the state when the thread is still alive but is currently not eligible to run. A thread that is blocked waiting for a monitor lock is in this state.
A running thread can transit to one of the non-runnable states depending on the situation. A thread remains in a non-runnable state until a special transition occurs. A thread doesn’t go directly to the running state from a non-runnable state but transits first to the Ready-to-run state.
The non-runnable states can be characterized as follows:
- Sleeping:- The thread sleeps for a specified amount of time.
- Blocked for I/O:- The thread waits for a blocking operation to complete.
- Blocked for Join completion: – The thread awaits completion of another thread.
- Waiting for notifications: – The thread awaits a notification from another thread.
- Blocked for lock acquisition: – The thread waits to acquire the lock of an object.
JVM executes a thread based on its priority and scheduling.
Example: Thread Life Cycle in Java
Here we are giving a simple example of the Thread life cycle. In this example, we will create a Java class where we will create a Thread, and then we will use some of its methods that represents its life cycle.
In this example, we have used the methods and indicated their purposes with the comment line. We have created two Thread subclasses named A1 and B. In both of the classes, we have to override the run() method and executed the statements. Then we created a ThreadLifeCycle.java class where we created instances of both classes and used the start() method to move the threads into the running state, yield() method to move the control to another thread, sleep() method to move into a blocked state. And after successful completion of the run() method the Thread is automatically moved into a Dead state.
A1.java
class A1 extends Thread { public void run () { System.out.println ("Thread A"); System.out.println ("i in Thread A "); for (int i = 1; i <= 5; i++) { System.out.println ("i = " + i); try { Thread.sleep (1000); } catch (InterruptedException e) { e.printStackTrace (); } } System.out.println ("Thread A Completed."); } }
B.java
class B extends Thread { public void run () { System.out.println ("Thread B"); System.out.println ("i in Thread B "); for (int i = 1; i <= 5; i++) { System.out.println ("i = " + i); } System.out.println ("Thread B Completed."); } }
ThreadLifeCycleDemo.Java
public class ThreadLifeCycleDemo { public static void main (String[]args) { // life cycle of Thread // Thread's New State A1 threadA = new A1 (); B threadB = new B (); // Both the above threads are in runnable state // Running state of thread A & B threadA.start (); // Move control to another thread threadA.yield (); // Blocked State of thread B try { threadA.sleep (1000); } catch (InterruptedException e) { e.printStackTrace (); } threadB.start (); System.out.println ("Main Thread End"); } }
Output:
Thread Scheduler in Java:
JVM implements one of the following scheduling strategies
- Preemptive scheduling: If a thread with a higher priority than the current running thread, then the current running thread is preempted(moves to the ready-to-run state) to let the higher priority thread execute.
- Time-sliced or Round-Robin scheduling: A running thread is allowed to execute for a fixed length of time, after which it moves to the Ready-to-run state to wait its turn to run again.
In the next article, I am going to discuss Thread Priority in Java with Examples. Here, in this article, I try to explain Thread Life Cycle in Java with examples. I hope you enjoy this Thread Life Cycle in Java with Examples article.