๐Ÿš€ Multithreaded Programming in Java: In-Depth Guide (Threads, Lifecycle, Runnable, Methods & Priority)


๐ŸŒŸ Introduction

In todayโ€™s world of high-performance applications, responsiveness and speed are crucial. Whether itโ€™s a web server handling thousands of users or a desktop app performing background tasks, Multithreading plays a vital role. ๐Ÿง โšก

Java provides built-in support for multithreaded programming, allowing multiple parts of a program to execute simultaneously.

๐Ÿ‘‰ In this detailed guide, we will deeply understand:

  • What is Multithreading (concept + real understanding)
  • Why and where it is used
  • Thread Lifecycle (with detailed explanation of each state)
  • Creating threads using Thread class and Runnable interface
  • Important Thread class methods (with working programs)
  • Thread Priority (how it works internally)
  • Common mistakes & tricky concepts
  • Interview questions with detailed answers

๐Ÿงต What is Multithreading?

Multithreading is the ability of a program to execute multiple threads concurrently.

๐Ÿ‘‰ A thread is the smallest unit of execution within a process.

๐Ÿง  Key Concept:

  • A process is a complete program (e.g., Chrome)
  • A thread is a task inside that program (e.g., loading tab, playing video)

๐Ÿ”ฅ Why Use Multithreading?

โœ… 1. Better CPU Utilization

CPU doesnโ€™t sit idle โ€” multiple threads keep it busy.

โœ… 2. Faster Execution

Tasks run in parallel (depending on CPU cores).

โœ… 3. Improved User Experience

UI does not freeze while performing background tasks.

โœ… 4. Real-world Applications

  • Web servers ๐ŸŒ
  • Gaming engines ๐ŸŽฎ
  • Banking systems ๐Ÿฆ
  • File downloading ๐Ÿ“ฅ

๐Ÿง  Understanding with Example

Imagine downloading a file:

  • Thread 1 โ†’ Download file
  • Thread 2 โ†’ Show progress bar
  • Thread 3 โ†’ Accept cancel request

๐Ÿ‘‰ All run simultaneously = Multithreading ๐Ÿ’ก


๐Ÿ”„ Thread Life Cycle (Detailed Explanation)

A thread does not start running immediately after creation. It passes through multiple states.

๐Ÿงฉ Thread States:


๐Ÿ”น 1. NEW ๐Ÿ†•

  • Thread is created using new Thread()
  • It has not started execution yet
Thread t = new Thread();

๐Ÿ”น 2. RUNNABLE โ–ถ๏ธ

  • After calling start()
  • Thread is ready but waiting for CPU

๐Ÿ”น 3. RUNNING ๐Ÿƒ

  • Thread scheduler assigns CPU
  • Thread executes run() method

๐Ÿ”น 4. BLOCKED / WAITING โธ๏ธ

Thread enters this state when:

  • Waiting for resource
  • Waiting for another thread
  • Using sleep(), wait(), join()

๐Ÿ”น 5. TERMINATED โŒ

  • Thread completes execution
  • Cannot be restarted

๐Ÿ“Š Lifecycle Flow

NEW โ†’ RUNNABLE โ†’ RUNNING โ†’ WAITING/BLOCKED โ†’ RUNNABLE โ†’ TERMINATED

๐Ÿงฑ Creating Threads in Java

There are two main approaches:


๐Ÿ”น Method 1: Using Thread Class


โœ… Complete Program

class MyThread extends Thread {

    @Override
    public void run() {
        // Code executed by thread
        for(int i = 1; i <= 5; i++) {
            System.out.println("Thread is running: " + i);
        }
    }

    public static void main(String[] args) {
        MyThread t1 = new MyThread();

        // Thread is in NEW state
        t1.start(); // Moves to RUNNABLE

        // Main thread execution
        for(int i = 1; i <= 5; i++) {
            System.out.println("Main thread: " + i);
        }
    }
}

๐ŸŒŸ Overview of the Program

This program demonstrates:

  • Creating a thread using Thread class
  • Running two threads simultaneously:
    • Main Thread ๐Ÿง 
    • Child Thread ๐Ÿงต

๐Ÿ‘‰ The goal is to show how Java executes multiple threads in parallel.


๐Ÿงฑ Step 1: Class Declaration

class MyThread extends Thread

๐Ÿ” Explanation:

  • MyThread is a custom class
  • It extends the Thread class, meaning:
    • It becomes a thread itself
    • It inherits thread behavior from Java

๐Ÿ‘‰ By extending Thread, we can override its run() method.


โš™๏ธ Step 2: Overriding run() Method

@Override
public void run() {
    for(int i = 1; i <= 5; i++) {
        System.out.println("Thread is running: " + i);
    }
}

๐Ÿ” Deep Explanation:

  • run() is the entry point of a thread
  • When a thread starts, this method is executed

๐Ÿ” Loop Behavior:

  • Runs from i = 1 to i = 5
  • Prints:Thread is running: 1 Thread is running: 2 ...

โš ๏ธ Important Concept:

๐Ÿ‘‰ This code is executed by the child thread, NOT the main thread.


๐Ÿง  Step 3: main() Method Execution

public static void main(String[] args)

This is where the program starts execution.


๐Ÿงต Step 4: Creating Thread Object

MyThread t1 = new MyThread();

๐Ÿ” What happens here?

  • A thread object is created
  • But thread has NOT started yet

๐Ÿ“Œ Thread State:

๐Ÿ‘‰ NEW State ๐Ÿ†•


๐Ÿš€ Step 5: Starting the Thread

t1.start();

๐Ÿ”ฅ What happens internally?

When start() is called:

  1. JVM creates a new thread
  2. Moves thread to RUNNABLE state
  3. Thread scheduler decides when to run it
  4. Internally calls run()

โš ๏ธ Very Important:

๐Ÿ‘‰ start() โ‰  run()

MethodBehavior
start()Creates new thread โœ…
run()Normal method call โŒ

๐Ÿง  Step 6: Main Thread Execution

for(int i = 1; i <= 5; i++) {
    System.out.println("Main thread: " + i);
}

๐Ÿ” Explanation:

  • This loop is executed by the main thread
  • Runs independently of the child thread

โšก Key Concept: Parallel Execution

At this point:

  • t1 thread is running run()
  • Main thread is running its loop

๐Ÿ‘‰ Both execute simultaneously


๐Ÿ“Š Possible Output (NOT FIXED โ—)

Main thread: 1
Thread is running: 1
Main thread: 2
Thread is running: 2
Thread is running: 3
Main thread: 3
Thread is running: 4
Main thread: 4
Thread is running: 5
Main thread: 5

๐Ÿคฏ Why output is mixed?

Because:

  • CPU switches between threads
  • This is called context switching

๐Ÿ‘‰ Execution order is NOT predictable


๐Ÿ”„ Thread Lifecycle in This Program

Step-by-step:

  1. new MyThread() โ†’ NEW ๐Ÿ†•
  2. start() โ†’ RUNNABLE โ–ถ๏ธ
  3. Scheduler picks thread โ†’ RUNNING ๐Ÿƒ
  4. Loop finishes โ†’ TERMINATED โŒ

๐Ÿง  Internal Working (Very Important)

When start() is called:

  • JVM does NOT immediately run run()
  • It sends thread to scheduler
  • Scheduler decides execution time

๐Ÿ‘‰ This is why output is unpredictable


๐Ÿ”น Method 2: Using Runnable Interface (Best Practice โœ…)


โœ… Complete Program

class MyRunnable implements Runnable {

    @Override
    public void run() {
        for(int i = 1; i <= 5; i++) {
            System.out.println("Runnable thread: " + i);
        }
    }

    public static void main(String[] args) {
        MyRunnable obj = new MyRunnable();

        Thread t1 = new Thread(obj); // Passing Runnable object
        t1.start();

        for(int i = 1; i <= 5; i++) {
            System.out.println("Main thread: " + i);
        }
    }
}

๐Ÿ” Why Runnable is Better?

  • Java does not support multiple inheritance
  • If you extend Thread, you cannot extend any other class โŒ
  • Runnable allows flexibility โœ…

โš™๏ธ Important Thread Class Methods (With Examples)


๐Ÿ”น 1. start() ๐Ÿš€

Starts a new thread.

Thread t = new Thread();
t.start();

๐Ÿ”น 2. sleep() ๐Ÿ˜ด

Pauses thread execution.

โœ… Example

class SleepDemo {
    public static void main(String[] args) throws InterruptedException {
        for(int i = 1; i <= 5; i++) {
            System.out.println(i);
            Thread.sleep(1000); // 1 second delay
        }
    }
}

๐Ÿ” Explanation:

  • Thread pauses for given milliseconds
  • Throws InterruptedException

๐Ÿ”น 3. join() ๐Ÿค

Waits for another thread to complete.

โœ… Example

class JoinDemo extends Thread {

    public void run() {
        for(int i = 1; i <= 5; i++) {
            System.out.println("Child Thread: " + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        JoinDemo t1 = new JoinDemo();
        t1.start();

        t1.join(); // Main thread waits

        for(int i = 1; i <= 5; i++) {
            System.out.println("Main Thread: " + i);
        }
    }
}

๐Ÿ”น 4. isAlive() ๐Ÿ”

Checks if thread is running.

System.out.println(t1.isAlive());

๐Ÿ”น 5. setName() / getName() ๐Ÿท๏ธ

t1.setName("WorkerThread");
System.out.println(t1.getName());

๐Ÿ”น 6. currentThread() ๐Ÿง 

System.out.println(Thread.currentThread().getName());

๐ŸŽฏ Thread Priority (Deep Understanding)

Every thread has a priority that helps the scheduler decide execution order.


๐Ÿ“Š Priority Levels:

ConstantValue
MIN_PRIORITY1
NORM_PRIORITY5
MAX_PRIORITY10

โœ… Complete Example

class PriorityDemo extends Thread {

    public void run() {
        System.out.println(Thread.currentThread().getName() + " Priority: " + Thread.currentThread().getPriority());
    }

    public static void main(String[] args) {
        PriorityDemo t1 = new PriorityDemo();
        PriorityDemo t2 = new PriorityDemo();

        t1.setName("Low Priority Thread");
        t2.setName("High Priority Thread");

        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.MAX_PRIORITY);

        t1.start();
        t2.start();
    }
}

๐Ÿ” Important Notes:

  • Higher priority โ†’ More chance of execution (NOT guaranteed โš ๏ธ)
  • Depends on OS scheduler
  • Do NOT rely heavily on priority for logic

โš ๏ธ Common Mistakes (VERY IMPORTANT)


โŒ 1. Calling run() directly

No multithreading happens.


โŒ 2. Ignoring Exception Handling

Thread.sleep(1000); // must handle exception

โŒ 3. Assuming order of execution

Threads execute unpredictably โ—


โŒ 4. Overusing threads

Too many threads โ†’ performance issues


โŒ 5. Not understanding shared data issues

Leads to:

  • Race conditions
  • Data inconsistency

๐Ÿคฏ Common Confusions


๐Ÿค” start() vs run()

Featurestart()run()
Thread createdโœ…โŒ
Async executionโœ…โŒ

๐Ÿค” Is multithreading always faster?

๐Ÿ‘‰ NO!

Depends on:

  • CPU cores
  • Task type
  • Overhead

๐Ÿ’ผ Interview Questions (Detailed)


โ“ What is a thread?

๐Ÿ‘‰ A lightweight unit of execution inside a process.


โ“ Difference between process and thread?

ProcessThread
HeavyweightLightweight
Separate memoryShared memory

โ“ What is thread lifecycle?

๐Ÿ‘‰ NEW โ†’ RUNNABLE โ†’ RUNNING โ†’ WAITING โ†’ TERMINATED


โ“ Why Runnable is preferred?

๐Ÿ‘‰ Allows flexibility and avoids inheritance limitations.


โ“ What is join()?

๐Ÿ‘‰ Makes one thread wait for another to finish.


โ“ What is sleep()?

๐Ÿ‘‰ Pauses execution for a specified time.


๐Ÿ Conclusion

Multithreading is a core concept in Java that enables efficient, high-performance applications. ๐Ÿš€

In this detailed guide, you learned:

  • โœ”๏ธ What multithreading is and why it matters
  • โœ”๏ธ Thread lifecycle with complete understanding
  • โœ”๏ธ Creating threads using Thread & Runnable
  • โœ”๏ธ Important thread methods
  • โœ”๏ธ Thread priority and behavior
  • โœ”๏ธ Common mistakes & interview preparation

๐ŸŽฏ Final Advice

๐Ÿ‘‰ Start practicing small programs
๐Ÿ‘‰ Observe thread behavior carefully
๐Ÿ‘‰ Move to advanced topics like:

  • Synchronization
  • Thread pools
  • Executors framework

๐Ÿ’ป Happy Coding! ๐Ÿ”ฅ

Multithreading may seem tricky at first, but once you master it โ€” it becomes one of your strongest Java skills ๐Ÿ’ช

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *