No history yet

Introduction to Java Multithreading

What is a Thread?

Think of a program as a series of tasks. In a simple program, these tasks run one after another in a single sequence. This is called a single-threaded application. It's like a chef in a kitchen who chops all the vegetables, then boils the water, then cooks the pasta, all in a strict order. Only one thing happens at a time.

A thread is a single, lightweight path of execution within a program. Multithreading is when a program splits itself into multiple threads that can run concurrently. Imagine our kitchen now has several chefs. One can chop vegetables while another boils water, and a third prepares the sauce. The whole meal gets ready much faster. That's the power of multithreading.

Multithreading is a technique that allows for concurrent (simultaneous) execution of two or more parts of a program for maximum utilization of a CPU.

In modern applications, this is essential. A word processor can check your spelling in one thread while you continue typing in another. A web server can handle multiple user requests simultaneously, each in its own thread. This leads to more responsive and efficient applications that don't freeze while performing a heavy task.

Creating Threads in Java

Java provides two primary ways to create a thread. Let's look at both.

Method 1: Extending the Thread Class

The first method is to create a new class that extends the java.lang.Thread class. You then override the run() method in your new class. This run() method contains the code that will be executed by the new thread.

class MyThread extends Thread {
    public void run() {
        // This is the code that will run in the new thread.
        System.out.println("MyThread is running!");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        thread1.start(); // This starts the new thread.
    }
}

Method 2: Implementing the Runnable Interface

The second, and often preferred, method is to implement the java.lang.Runnable interface. Your class must then implement the run() method. To run it, you create an instance of your class, pass it to the constructor of a Thread object, and then call the start() method on the Thread object.

This approach is more flexible. Since Java does not support multiple inheritance, if your class already extends another class, you can't also extend Thread. Implementing the Runnable interface gets around this limitation.

class MyRunnable implements Runnable {
    public void run() {
        // This is the code that will run in the new thread.
        System.out.println("MyRunnable is running!");
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread2 = new Thread(myRunnable);
        thread2.start(); // This starts the new thread.
    }
}

Starting the Thread

In both examples, you saw the start() method. This is a crucial detail. Calling start() is what actually creates a new thread and tells the Java Virtual Machine (JVM) to schedule it for execution. The JVM then calls the run() method in that new thread.

What happens if you call run() directly instead of start()? The code inside run() will execute, but it will do so in the current thread. No new thread will be created. Always use start() to achieve multithreading.

This diagram shows the main program thread initiating two new threads. Once started, all three threads can execute concurrently, allowing the program to perform multiple operations at once.

Quiz Questions 1/5

What is a single-threaded application?

Quiz Questions 2/5

Using the analogy of chefs in a kitchen, multithreading is most like...