Multithreading Basics & The Lifecycle of a Thread in Java
1. Basic Idea of Multithreaded Programming
Before understanding multithreading, let us understand what a Thread is:
- Process (Heavyweight): An independent program currently executing in memory (e.g., MS Word, Chrome, VLC Player). Each process has its own separate memory address space.
- Thread (Lightweight Sub-Process): The smallest independent unit of execution within a single process. Multiple threads inside the same program share the same Heap memory space, making switching between threads extremely fast!
Multithreading in Java is the capability of a Java program to execute two or more threads concurrently (simultaneously) to maximize CPU utilization.
Simple Real-Life Analogy: Imagine you are typing an assignment in MS Word:
- Thread 1 reads your keyboard strokes and shows letters on screen.
- Thread 2 simultaneously checks your spelling and underlines mistakes in red.
- Thread 3 auto-saves your document in the background every 60 seconds. Because all three threads run concurrently inside one software, MS Word never freezes while checking spelling!
Comparison: Process-Based Multitasking vs Thread-Based Multithreading
| Feature | Process-Based Multitasking | Thread-Based Multithreading |
|---|---|---|
| 1. Basic Unit | Process (two or more separate programs running at once). | Thread (two or more parts of the same program running at once). |
| 2. Weight & Overhead | Heavyweight; context switching between processes is slow and expensive. | Lightweight; context switching between threads is very fast. |
| 3. Memory Sharing | Every process has its own separate memory space in RAM. | All threads of a process share the same Heap memory space. |
| 4. Inter-Communication | Inter-process communication (IPC) is slow and complex. | Inter-thread communication (wait(), notify()) is simple and fast. |
2. The Main Thread in Java
Even if you do not create a single thread yourself, every Java program has at least one thread: the main thread!
When you run a Java program, the JVM automatically creates a thread named "main" to execute your public static void main(String[] args) method. From inside main(), you can spawn additional child threads.
public class MainThreadDemo {
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println("Current Thread Name: " + t.getName()); // Output: main
System.out.println("Current Priority : " + t.getPriority()); // Output: 5
}
}
3. The Lifecycle of a Thread in Java
During its lifetime, a thread in Java passes through 5 distinct states from its birth (new) until its death (Terminated). This is one of the most frequently asked 8-mark questions in DAVV BCA exams!
Thread t = new MyThread();t.start() →run() on CPUrun() finishes →(Note: From RUNNING, a thread can temporarily move to 4. BLOCKED / WAITING / TIMED_WAITING when sleep(), wait(), join(), or I/O blocking occurs, and returns to RUNNABLE once the wait is over).
Detailed Explanation of the 5 States of a Thread
1. New (Born State)
- When a thread object is created using the
newoperator (Thread t = new MyThread();), the thread is said to be in the New state. - At this point, the thread is just an empty object in memory—it is not yet alive, and no system resources or CPU time have been allocated to it.
- Calling
t.start()moves the thread from New → Runnable.
2. Runnable (Ready-to-Run State)
- After
t.start()is invoked, the thread enters the Runnable pool (ready queue). - In this state, the thread is alive and completely ready to run, waiting only for the Thread Scheduler (part of the JVM/OS) to allocate CPU time to it.
3. Running State
- When the Thread Scheduler selects a thread from the Runnable pool and gives it the CPU, the thread enters the Running state and begins executing the code inside its
run()method. - A running thread can voluntarily give up the CPU using
Thread.yield(), or be pre-empted by a higher-priority thread, moving it back to the Runnable state.
4. Blocked / Waiting / Timed Waiting (Non-Runnable State)
- A running thread enters the Blocked / Waiting state when it is alive but temporarily unable to run because it is waiting for an external event or timer.
- How a thread enters this state:
- Calling
Thread.sleep(milliseconds): Pauses execution for a specified time. - Calling
wait(): Waits until another thread callsnotify()ornotifyAll(). - Calling
t2.join(): Waits for another threadt2to finish executing. - Waiting for I/O operations (like user keyboard input) or waiting to acquire a
synchronizedlock.
- Calling
- How it leaves this state: Once the sleep timer expires,
notify()is called, or I/O completes, the thread does not jump directly to Running—it goes back to the Runnable queue!
5. Terminated (Dead State)
- A thread enters the Terminated (Dead) state when its
run()method finishes executing normally or when an unhandled exception abortsrun(). - Important Rule: Once a thread is Dead/Terminated, it cannot be started again! Calling
t.start()a second time on a terminated thread throwsIllegalThreadStateException.
4. Important Methods of the Thread Class Controlling the Lifecycle
| Method | Effect on Thread Lifecycle |
|---|---|
start() |
Allocates a new call stack for the thread, moves it from New → Runnable, and internally invokes run(). |
run() |
Contains the actual task/code that the thread executes when in the Running state. |
Thread.sleep(long ms) |
Pauses the currently executing thread for ms milliseconds (throws InterruptedException). |
join() |
Causes the current thread to wait until the thread on which join() is called terminates. |
Thread.yield() |
Hints to the Thread Scheduler that the current thread is willing to pause and let other threads of equal priority run. |
isAlive() |
Returns true if the thread has been started (start()) and has not yet terminated. |
💡 Exam Preparation Tips for DAVV BCA
- Always draw the 5-state Thread Lifecycle diagram (
New→Runnable↔Running→Terminated, withBlocked/WaitingbelowRunningandRunnable). - Never forget to mention the transitional methods on the arrows:
start(),sleep(ms),wait()/notify(),join(), and completion ofrun().