Key Points
- A thread in Java represents a specific flow of execution within a program, with its own program counter, stack, and local variables.
- Threads in Java can work together using common data and constructs, with the language offering a wide range of APIs.
- The life cycle of a thread in Java includes the new, runnable, running, and terminated stages.
- In the terminated stage, a thread cannot restart, making it crucial to understand termination conditions.
When you’re working with the dynamics of high-level objects, it’s helpful to understand how their execution works. Understanding the life cycle of threads in Java allows you to manage them effectively, including their flow, interaction, and synchronization.
So where do you even begin? In this article, we talk about threads and their patterns. This gives you a base to start on. We even provide a sample syntax to see the life cycle play out in real-time. So let’s get into threads and their mechanisms below.
What Is the Life Cycle of a Thread in Java
Before we get into the life cycle of threads in Java, it’s important to understand what a thread is in the first place. This term represents a specific flow of execution within a program. Each thread has an individual program counter, stack, and local variables that allow it to execute paths on its own.
Threads have the ability to work together using common data and constructs. In Java, these are easy to deal with, as the language uses a wide range of APIs. As such, it’s essential to understand the life cycle of threads in Java as it pertains to each concurrent thread’s execution. Let’s learn more about it below.
How Does the Life Cycle Work?
Each flow of execution within the program works independently, but they all follow a common life cycle. While some threads have unique states or variations, the common pattern goes like this:
- New
- Runnable
- Running
- Terminated
In the new stage, we’re creating the thread. It’s now within the code, although it’s not prepared to run.
In the runnable stage, we’ve called the “start()” method. While the thread still hasn’t been executed yet, it’s now eligible. You can call on the thread whenever you’re ready to use it.
In the running stage, the thread is being used.
In the terminated stage, the thread completed its task or received a stop method. When a thread enters the terminated stage, it cannot restart. Therefore, it’s important to understand the termination conditions of your threads so they end when intended.
In the example below, we’ve created a thread that prints out its current state. You can use this code to see how a thread progresses through its life cycle.
public class ThreadLifecycleExample {
public static void main(String[] args) {
// Create a new thread
Thread thread = new Thread(() -> {
System.out.println("Thread is running");
});
// Start the thread
thread.start();
// Get the current state of the thread
Thread.State state = thread.getState();
System.out.println("Thread state after start: " + state);
// Wait for the thread to complete execution
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Get the state of the thread after it has completed
state = thread.getState();
System.out.println("Thread state after completion: " + state);
}
}
In addition to the basic life cycle of thread in Java, other variations exist. For example, “timed waiting” suggests that a thread must wait for a specific duration. Or you might find a thread parked when it’s suspended using low-level synchronization. Other special case states include:
- Blocked/Waiting
- Terminated but Not Garbage Collected
- Interrupted
Summary Table
Thread Stage | Description |
---|---|
New | Thread is created but not prepared to run |
Runnable | Thread is eligible to run after calling the ‘start()’ method |
Running | Thread is being used |
Terminated | Thread completed its task or received a stop method |
The image featured at the top of this post is ©Joyseulay/Shutterstock.com.