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.