←Back to Subject
Notes
Notes
Study material and explanations
Diagrams
Diagrams
Visualize concepts easily
Mnemonics
Mnemonics
Tricks to remember faster
One Night Prep
One Night Prep
Short and focused revision
Revision
Revision
Quick summary and key points
Important Questions
Important Questions
Practice most relevant questions
Notes

Multithreading Basics & The Lifecycle of a Thread in Java

Study material and explanations for Unit 3

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!

Figure 3.1: State Transition Diagram — The Lifecycle of a Thread in Java
1. NEW (Born)Thread t = new MyThread();
→ t.start() →
2. RUNNABLEReady in queue waiting for CPU
→ Scheduler picks →
3. RUNNINGExecuting run() on CPU
→ run() finishes →
5. TERMINATEDDead (Cannot restart)

(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 new operator (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:
    1. Calling Thread.sleep(milliseconds): Pauses execution for a specified time.
    2. Calling wait(): Waits until another thread calls notify() or notifyAll().
    3. Calling t2.join(): Waits for another thread t2 to finish executing.
    4. Waiting for I/O operations (like user keyboard input) or waiting to acquire a synchronized lock.
  • 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 aborts run().
  • Important Rule: Once a thread is Dead/Terminated, it cannot be started again! Calling t.start() a second time on a terminated thread throws IllegalThreadStateException.

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, with Blocked/Waiting below Running and Runnable).
  • Never forget to mention the transitional methods on the arrows: start(), sleep(ms), wait() / notify(), join(), and completion of run().