Java Multithreading: Thread Class, Runnable Interface & Concurrency

Multithreading is a core feature of Java that enables concurrent execution of two or more parts of a program for maximum utilization of modern multi-core CPU hardware. A Thread is the smallest lightweight unit of dispatchable execution within a process.

Process vs. Thread:

  • Process: An independent operating system program with its own dedicated memory space (heavyweight).
  • Thread: A lightweight path of execution inside a process. All threads inside a Java application share the Heap memory, but each thread maintains its own independent Call Stack and Program Counter (PC).

The 2 Traditional Ways to Create a Thread in Java

Approach 1: Extending the java.lang.Thread Class

class WorkerThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread running: " + Thread.currentThread().getName());
    }
}

public class ThreadDemo1 {
    public static void main(String[] args) {
        WorkerThread t1 = new WorkerThread();
        t1.setName("Worker-Alpha");
        t1.start(); // Spawns new thread on OS!
    }
}

Approach 2: Implementing java.lang.Runnable (Best Practice)

Because Runnable is a @FunctionalInterface, it can be written cleanly as a lambda expression:

public class RunnableDemo {
    public static void main(String[] args) {
        // Lambda implementation of Runnable
        Runnable task = () -> {
            for (int i = 1; i <= 3; i++) {
                System.out.println("Processing async step " + i + " on " + Thread.currentThread().getName());
            }
        };

        Thread worker = new Thread(task, "BackgroundWorker");
        worker.start();
    }
}

University Exam Corner (BCA / B.Sc CS)

Exam Question: "What happens if you invoke t.start() twice on the exact same Thread instance?"

Answer: The JVM throws java.lang.IllegalThreadStateException! A thread can only be started once in its entire lifecycle. Once it completes or starts, it cannot be restarted.

Next Step

Now let us examine the 6 states of the Java Thread Lifecycle. Proceed to: Java Thread States & Lifecycle →

Frequently Asked Questions (FAQ)

Q1. What is the difference between extending Thread and implementing Runnable in Java?
Implementing Runnable is universally preferred because Java allows single class inheritance (if you extend Thread, you cannot extend any other class). Runnable separates the task logic from the thread runner and works seamlessly with Executor thread pools.
Q2. What is the difference between t.start() and t.run()?
t.start() allocates a brand-new call stack from the OS kernel and invokes run() concurrently in that separate thread. t.run() merely executes the run() method synchronously on the current caller thread like a normal method call.
Q3. What is a Daemon Thread in Java?
A Daemon Thread is a low-priority background support thread (e.g. Garbage Collector). When all non-daemon user threads finish executing, the JVM shuts down immediately without waiting for daemon threads to complete.

Explore Related Java Tutorials

Accelerate your Java mastery by studying these tightly connected core tutorials:

Thread States & Lifecycle →

NEW, RUNNABLE, BLOCKED states.

Thread Synchronization →

Preventing race conditions.

Executor Framework →

Thread pools in enterprise apps.

Java 21 Virtual Threads →

Modern lightweight concurrency.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!