JAVA - Zero to Hero / Multithreading

Multithreading Examples

🧡 Thread by Extending Thread Class

βœ… Code:

class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println("Thread running: " + i);
        }
    }

    public static void main(String[] args) {
        MyThread t1 = new MyThread(); // Create a thread object
        t1.start(); // Starts a new thread that runs run()

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

πŸ” Key Differences Between Thread and Runnable

Feature

Thread Class

Runnable Interface

🧱 Inheritance

Extends Thread class directly

Implements Runnable interface

πŸ“Œ Limitation

Cannot extend any other class (Java doesn't support multiple inheritance)

Can implement other interfaces or extend other classes

🧠 Design Philosophy

Tightly coupled β€” thread code and thread logic are mixed

Loosely coupled β€” separates thread code from logic

βœ… Preferred For

Simple, short-lived tasks

Reusability, flexibility, cleaner design

πŸ” Object Sharing

Cannot share same thread instance

Multiple threads can share the same Runnable object

🧩 Code Reusability

Less reusable

Highly reusable

πŸ› οΈ Syntax Simplicity

Slightly simpler syntax

Slightly more complex, but more powerful

🧠 Explanation:

  • Two threads are running: the main thread and t1 thread.

  • They execute independently and may overlap.

  • Order of output may change each time due to thread scheduling.


🧡 Thread by Implementing Runnable Interface

βœ… Code:

class MyRunnable implements Runnable {
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println("Runnable thread: " + i);
        }
    }

    public static void main(String[] args) {
        MyRunnable obj = new MyRunnable();     // Runnable object
        Thread t1 = new Thread(obj);           // Thread object with Runnable
        t1.start();                            // Starts new thread

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

🧠 Explanation:

  • Runnable is implemented instead of extending Thread.

  • Runnable object passed to a Thread, then start() is used.

  • Again, output may interleave randomly.


🧡 Multiple Threads Running Together

βœ… Code:

class MyTask extends Thread {
    public void run() {
        for (int i = 1; i <= 2; i++) {
            System.out.println(Thread.currentThread().getName() + ": Task " + i);
        }
    }

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

        t1.setName("Thread-1");
        t2.setName("Thread-2");

        t1.start();
        t2.start();
    }
}
Thread-1: Task 1
Thread-2: Task 1
Thread-1: Task 2
Thread-2: Task 2

🧠 Explanation:

  • Two separate threads (t1 and t2) print messages.

  • Each runs its own run() method.

  • Threads are named for clarity.

  • Output order is not fixed.


πŸ’€ Thread Sleep Example

βœ… Code:

class SleepDemo extends Thread {
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println("Count: " + i);
            try {
                Thread.sleep(1000); // Sleep for 1 second (1000 ms)
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }
    }

    public static void main(String[] args) {
        SleepDemo t = new SleepDemo();
        t.start();
    }
}
Count: 1
(wait 1 second)
Count: 2
(wait 1 second)
Count: 3

🧠 Explanation:

  • Thread.sleep(1000) makes the thread pause for 1 second between prints.

  • Used to control the execution speed or simulate real-time actions.

  • InterruptedException must be handled.