← Back to Multithreading Course

Class 6: Thread Lifecycle and Thread States

Understand the different states a thread goes through during its lifetime, from creation to completion.

1. Quick Recap: What Have We Learned So Far?

In our previous classes, we learned how to create threads using the Thread class and Runnable interface.

We also learned how lambda expressions make our code shorter, how to identify the currently executing thread, and how to give meaningful names to threads.

Now let's understand something important: Does a thread start executing as soon as we create it?

No. A thread goes through different stages during its lifetime. These stages are called thread states.

2. What Is the Lifecycle of a Thread?

Think about a simple everyday activity.

Imagine you are preparing a cup of tea:

  • First, you decide to make tea.
  • Then, you start preparing it.
  • You may wait for the water to boil.
  • Finally, the tea is ready.

Similarly, a thread also goes through different states. It is created, started, may wait or become temporarily blocked, and eventually finishes its work.

Java defines six thread states. Let's understand each one in simple terms.

3. The Six Thread States in Java

1. NEW

A thread is in the NEW state when we have created its Thread object but have not started it yet.

For example:

Thread thread = new Thread(() -> {
    System.out.println("Hello");
});

We have created the thread, but we have not called start().

Therefore, its state is NEW.

2. RUNNABLE

When we call start(), the thread moves from NEW to RUNNABLE.

thread.start();

A thread in the RUNNABLE state is ready to run or is currently running.

Java does not define a separate RUNNING state. Both ready-to-run and currently-running threads are represented by RUNNABLE.

3. BLOCKED

Imagine that two people want to enter the same room, but only one person can use the room at a time.

The second person must wait until the first person leaves.

A similar situation can happen with threads.

A thread enters the BLOCKED state when it is waiting to acquire a lock so that it can enter a synchronized section of code.

Once the lock becomes available, the thread can continue.

4. WAITING

Sometimes a thread needs to wait for another thread or for some specific action to happen.

For example, one thread may wait for another thread to finish its work.

In such situations, a thread can enter the WAITING state.

We will understand this better when we learn about join() and wait() in later classes.

5. TIMED_WAITING

What if a thread needs to wait only for a specific amount of time?

For example, it may need to pause for two seconds before continuing its work.

In this situation, the thread can enter the TIMED_WAITING state.

Methods such as sleep() can put a thread into this state.

We will explore sleep() in our next class.

6. TERMINATED

A thread reaches the TERMINATED state when it has completed its execution.

For example:

Thread thread = new Thread(() -> {
    System.out.println("Task completed");
});

thread.start();

Once the task finishes, the thread reaches the TERMINATED state.

A terminated thread cannot be started again.

4. Let's See the Thread Lifecycle Together

Now that we understand all six states, let's look at how a thread can move through them.

NEW
 |
 | start()
 v
RUNNABLE
 |
 | May need to wait for a lock
 v
BLOCKED

RUNNABLE
 |
 | Waits for another action
 v
WAITING

RUNNABLE
 |
 | Waits for a specified time
 v
TIMED_WAITING

RUNNABLE
 |
 | Task finishes
 v
TERMINATED

This is a simplified illustration, not a fixed sequence that every thread must follow.

A thread can move between RUNNABLE and other waiting states depending on what it needs to do.

Not every thread will enter BLOCKED, WAITING, or TIMED_WAITING. A simple thread may move from NEW to RUNNABLE and then to TERMINATED.

5. How Can We Find the State of a Thread?

Java provides a method called getState() to find the current state of a thread.

Let's look at a simple example:

public class Main {

    public static void main(String[] args) {

        Thread thread = new Thread(() -> {
            System.out.println("Task is running");
        });

        System.out.println(thread.getState());

        thread.start();

        System.out.println(thread.getState());
    }
}

Before starting the thread, the output will be:

NEW

After calling start(), the thread enters RUNNABLE. However, the second printed state may vary.

Why? Because the new thread may finish its task before getState() is called again.

Therefore, the second output could be RUNNABLE or TERMINATED.

Remember that getState() gives us a snapshot of the thread's state at that particular moment. The state can change immediately afterwards.

6. Important Things to Remember

  • Java defines exactly six thread states.
  • Creating a Thread object puts it in the NEW state.
  • Calling start() makes it eligible to run, moving it into RUNNABLE.
  • RUNNABLE represents both ready-to-run and currently-running threads.
  • BLOCKED means waiting to acquire a lock.
  • WAITING means waiting for another action without a time limit.
  • TIMED_WAITING means waiting for a specified amount of time.
  • TERMINATED means the thread has finished execution.
  • A terminated thread cannot be started again.

7. Try It Yourself

Create a simple Java program that:

  • Creates a thread that prints a message.
  • Prints its state before calling start().
  • Starts the thread.
  • Prints its state again.

Run the program a few times and observe the output. You may notice that the state after starting the thread is not always the same.

This is a good opportunity to understand that thread execution happens independently of the main thread.

8. Test Your Understanding

Answer these five questions to check what you have learned.

Question 1: How many states are defined for a Java thread?

Question 2: What is the state of a thread after creating its Thread object but before calling start()?

Question 3: What does the BLOCKED state represent?

Question 4: Which state represents a thread waiting for a specified amount of time?

Question 5: What happens when a thread completes its execution?

9. Class Summary

In this class, we learned about the lifecycle of a Java thread and its six possible states:

  • NEW
  • RUNNABLE
  • BLOCKED
  • WAITING
  • TIMED_WAITING
  • TERMINATED

We also learned how to use getState() to check the current state of a thread.

🎉 Congratulations! You Have Completed Part 1!

You have successfully completed the first part of our Java Multithreading course!

Take a moment to appreciate how far you have come. You started by understanding what multithreading is, and now you know how to create threads, define tasks, use lambda expressions, identify threads, and understand their lifecycle.

These are the foundations of Java multithreading. Make sure you are comfortable with these concepts before moving ahead.

Keep practising the examples, experiment with the code, and don't worry if everything doesn't become clear immediately. Learning takes time.

Well done! Now let's move forward. 🚀

Welcome to Part 2 — Working with Threads

Now that we know how to create threads, let's learn how to control their execution, wait for them, and communicate when a thread needs to stop.

Here is what we will learn next:

  • Class 7: Pausing a Thread with sleep()
  • Class 8: Waiting for a Thread with join()
  • Class 9: Interrupting a Thread
  • Class 10: Thread Scheduling and Daemon Threads

We will take each concept one step at a time. Let's keep learning!

Your Course Progress

0% Completed

You have completed 6 out of 44 classes.