Life Cycle of a Thread in Java

Learn via video course
FREE
View all courses
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Topics Covered

Overview

The thread life cycle in Java is an important concept in multithreaded applications. Although Sun (now Oracle) defines the thread life cycle with only four states, it's useful to consider six states to clarify the connections and get better understanding of them. These six states are: New, Runnable, Blocked, Waiting, Timed Waiting, and Terminated. The JVM manages a thread's life cycle when written in Java, and understanding these states can help develop more efficient and reliable multithreaded applications.

Introduction

Before we discuss thread life cycle in Java, let’s understand multithreading.

Multithreading extends the idea of performing multiple tasks at the same time, which is applicable in real life as well. For example, in a railway ticket reservation system, multiple customers can access the server at the same time to book their tickets.

A Java thread goes through several stages in its life cycle, including being created, started, running, and eventually dying. To better understand these states during thread execution, we'll use an illustrated graphic and helpful code examples.

Java Thread States: Thread Life Cycle in Java

Multithreading in Java is implemented using the java.lang.Thread class, which contains a static enumeration called State that defines the potential states of a thread. These states represent the phases through which a thread passes during its execution. At any given moment, a thread can be in one of the following states:

  • New
  • Runnable
  • Blocked
  • Waiting
  • Timed waiting
  • Terminated

The diagram shown below depict various states of a thread in Java at any instant of time:

life cycle of thread in java

Let’s now understand each thread state in detail:

1. New

A thread goes through this state when it is newly created by instantiating the Thread class but the start() method hasn’t been invoked yet. At this state, the thread is not considered alive as its execution has not started yet.

The following code snippet demonstrates a thread in its NEW state:

In the above example, we’ve created a new thread by calling the Thread constructor by passing a lambda expression. This lambda expression instantiates the functional interface Runnable with an empty body of the run() method.

Here’s the output of the above code snippet:

2. Runnable

A java thread goes through this state after the invocation of the start() method. At this state, a thread is considered alive because it is either running or ready for execution, but waiting for resource allocation.

In a multi-threaded environment, Thread Scheduler allocates a time slot for each thread. So, each thread runs for a particular amount of time and then relinquishes the resource to other threads in the runnable state.

In the above example, we’ve created a new thread and called its start() method.

Here’s the output of the above code snippet:

This output is uncertain because it is possible that the thread in java is immediately scheduled by the Thread Scheduler and may finish execution before the control reaches the thread.getState().

3. Blocked or Non-runnable

A thread goes through this state when it is temporarily inactive and not eligible to run. It enters this state when it is waiting to acquire a monitor lock and is trying to access a synchronized block or method, which means only one thread can access the particular resource or method at a time. We can synchronize a specific block of code in a method or a whole method.

In the above example, we’ve created two different threads. At first, thread1 starts and executes its run() method to acquire a lock on the synchronized method performTask(). This method has an infinite loop so thread1 will keep running forever. After some time, thread2 starts and executes its run() method and will end up in the blocked state because it cannot acquire a lock on the performTask() method.

Here’s the output of the above code snippet:

4. Waiting

A java thread goes through this state when it is waiting for another thread to perform a particular activity prior to what the current thread is doing. It enters this state when its wait() method is invoked. When this prior action is completed, the scheduler is notified to change the state of the thread to runnable and move it back to the thread pool.

In the above example, thread1 is created and started and its run() method is executed. In the run() method of thread1, thread2 is created and started and its run() method is executed. While the processing of thread2 continues, the join() method on thread2 is invoked that makes thread1 wait until thread2 completes its execution.

Here’s the output of the above code snippet:

5. Timed Waiting

A thread in java goes through this state when it is waiting for another thread to perform some action for a specific period. A thread lies in this state until the timed interval expires or until it’s notified by another thread and then it returns to the runnable state. A thread enters this state when its sleep(long millis) or wait(long millis) method is invoked.

In the above example, a thread is created and started. When its run() method is executed, it enters sleep mode with a timeout period of 5 seconds. During this time, the thread remains in the timed-waiting state until the timed interval is expired, and then it returns to the runnable state.

Here’s the output of the above code snippet:

6. Terminated

A thread in java goes through this last state of its lifetime when it is successfully executed or was abnormally terminated and no longer consuming any cycles of CPU. It enters this state when its run() method is entirely executed when it exits the run() method, or when its stop() method is invoked. In this situation, a thread is considered dead, and thus if the start() method is invoked on the dead thread, it’ll raise an IllegalThreadStateException.

In the above example, we’ve created and started a thread. Then we blocked the main thread for 2 seconds using the sleep() method. Since our thread is an empty thread, this will give enough time to complete its execution and enter into the terminated state.

Here’s the output of the above code snippet:

Conclusion

  • Multithreading allows performing multiple tasks simultaneously, and a Java thread goes through several stages in its life cycle, including being created, started, running, and eventually dying.

  • The java.lang.Thread class contains a static enumeration called State that defines the potential states of a thread, and at any given moment, a thread can be in one of the following states: New, Runnable, Blocked, Waiting, Timed waiting, or Terminated.

  • The JVM manages a thread's life cycle when written in Java, and understanding these states can help develop more efficient and reliable multithreaded applications. The six states of the thread life cycle in Java are: New, Runnable, Blocked, Waiting, Timed Waiting, and Terminated.

  • New state: Occurs when a thread is created but not yet started.

  • Runnable state: Occurs after the start() method is invoked, and the thread is alive and either running or waiting for resource allocation.

  • Blocked state: Occurs when a thread is temporarily inactive and waiting to acquire a monitor lock to access a synchronized block or method.

  • Waiting state: Occurs when a thread is waiting for another thread to perform a specific action.

  • Terminated state: Occurs when a thread has finished execution.

  • Multithreading is a powerful tool in Java and understanding its meaning and usage helps us in optimizing and controlling our multithreaded programs.

  • There are many useful applications of multithreading, for example, spelling checker in a word document, multithreaded web servers serving multiple clients at the same time, gaming applications doing several tasks like updating score, playing sound, updating GUI, etc.