Multithreading in Java

Multithreading in Java

April 6th, 2026
1848
8:00 Minutes

Multithreading in Java is a programming concept that allows a single program to execute multiple threads concurrently. Each thread represents an independent path of execution, enabling tasks such as file downloads, data processing, and user interface updates to run simultaneously. It can be a handy skill for Java developers.

Are you one of them? Then, this blog is created for individuals like you to help you understand what multithreading is in Java. It will discuss the meaning, the lifecycle, and different ways to create a thread in Java.

Master Java Programming with Java Training

Boost your coding skills and gain hands-on knowledge in Java.

Explore Now

What is Multithreading in Java?

'What is Multithreading in Java?' is obviously the first question in our readers' minds. Here is what you need to know: Java Multithreading allows a program to execute multiple threads at the same time. It lets tasks run in parallel and makes better use of the CPU. A thread is a lightweight and independent unit of execution within a program. Here are two things that you must keep in mind. The first one is that a program can have multiple threads. Another one is that each thread operates independently and all share the same memory space.

Example

Let me give you a real-life example to help with your understanding. Imagine a coffee shop where multiple baristas (Threads) are preparing different kinds of coffees at the same time. It speeds up the process and utilizes all available resources (CPU).

What is Multithreading in Java

Read Also: What is Java Used For? Key Applications and Benefits Explained

Lifecycle of a thread in Java Multithreading

The lifecycle of a thread in Java Multithreading travels through a number of stages. It starts with the formation of the thread and ends with its finishing. Here is a diagram to display the complete lifecycle and the given steps to understand it better-

Lifecycle of a thread in Java Multithreading

  • New- The thread enters a new state or a 'born' state once it is created. It stays there until .start() is invoked.
  • Runnable- As soon as a fresh thread gets launched with .start(), it jumps into a runnable state to actively perform its task.
  • Waiting- There are a few instances where a thread pauses and enters the waiting state. It waits for another thread to complete a task in this state. It becomes runnable again once the other thread signals it to continue.
  • Timed Waiting- A runnable thread may enter the Timed Waiting state when it is waiting for a set period. It returns to the runnable state either when the timeout expires or the awaited event happens.
  • Terminated (Dead)- A runnable thread moves into the terminated state once it's done with the task or is otherwise stopped.

Different Ways to Create Threads

You can follow either of the two mechanisms to create threads, which I have discussed below with examples-

1. Extending the Thread Class

The first step is defining the class that extends Thread and overrides its run () method to specify the task. The next step is to create an instance of this class and invoke start (). This would trigger the run () method and initiate the thread's execution. You can extend the thread class if your class does not extend any other class.

Example

Coffee Shop (Extending Thread)

class BrewingTask extends Thread {

private String task;

BrewingTask(String task) {

this.task = task;

}

public void run() {

System.out.println(task + " is being prepared by " +

Thread.currentThread().getName());

}

}

public class Coffee {

public static void main(String[] args) {

Thread t1 = new BrewingTask("Espresso");

Thread t2 = new BrewingTask("Mocha");

Thread t3 = new BrewingTask("Americano");

Thread t4 = new BrewingTask("Latte");

t1.start();

t2.start();

t3.start();

t4.start();

}

}

Output

This is what the output would look like-

Espresso is being prepared by Thread-1

Mocha is being prepared by Thread-3

Americano is being prepared by Thread-2

Latte is being prepared by Thread-0

Explanation

Here is a little explanation for you-

  • We formed multiple threads from t1 to t4 using the BrewingTask class.
  • Each thread is a representation of a coffee type being prepared.
  • Invoking start () runs them concurrently.

2. Implementing the Runnable Surface

We create a class that implements the java.lang.Runnable interface and define its run() method. The next step is to create a Thread object passing the Runnable instance and call start () on the Thread object to begin execution. You can go for implementing the runnable surface if the class already extends another one.

Example

Coffee Shop (Runnable Interface)

class BrewingJob implements Runnable {

private String task;

BrewingJob(String task) {

this.task = task;

}

public void run() {

System.out.println(task + " is being prepared by " +

Thread.currentThread().getName());

}

}

public class BrewingRunnable {

public static void main(String[] args) {

Thread t1 = new Thread(new BrewingJob("Latte"));

Thread t2 = new Thread(new BrewingJob("Mocha"));

Thread t3 = new Thread(new BrewingJob("Espresso"));

t1.start();

t2.start();

t3.start();

}

}

Output

This is what the output would look like-

Latte is being prepared by Thread-2

Mocha is being prepared by Thread-1

Espresso is being prepared by Thread-0

Explanation

Here is a little explanation for you-

  • BrewingJob implements Runnable and overrides run ().
  • We send a Runnable object to the thread constructor.
  • Invoking start () runs them in parallel.

Creating a Thread by Implementing a Runnable Interface

Implement the runnable surface to enable a class to run as a thread. It has the following three steps-

Implement run () Method

The first step is to implement the run() method from the Runnable interface. This serves as the thread's entry point and your complete business logic should go inside it.

public void run( )

Instantiate a thread object

Follow the given constructor to instantiate a thread object in the second step-

Thread(Runnable threadObj, String threadName);

Call thread using start () method

Invoke the start () method after creating a thread object to launch it. This kicks off the run () method in a new thread of execution.

void start();

Read Also: Top 70 Java MCQs With Answers

Creating a Thread By Extending a Thread Class

The second way is to create a thread by defining a class that extends Java's Thread class. This approach is done in two ways and gives the benefit of direct access to thread-specific methods like start (), sleep () or interrupt (). This gives you more control over thread behaviour.

Override the run () method

You need to override the run () method from the thread class. This method serves as the thread's starting point and should contain all your business logic.

class RunnableDemo implements Runnable {

private Thread t;

private String threadName;

RunnableDemo( String name) {

threadName = name;

System.out.println("Creating " + threadName );

}

public void run() {

System.out.println("Running " + threadName );

try {

for(int i = 4; i > 0; i--) {

System.out.println("Thread: " + threadName + ", " + i);

// Let the thread sleep for a while.

Thread.sleep(50);

}

} catch (InterruptedException e) {

System.out.println("Thread " + threadName + " interrupted.");

}

System.out.println("Thread " + threadName + " exiting.");

}

public void start () {

System.out.println("Starting " + threadName );

if (t == null) {

t = new Thread (this, threadName);

t.start ();

}

}

}

public class TestThread {

public static void main(String args[]) {

RunnableDemo R1 = new RunnableDemo( "Thread-1");

R1.start();

RunnableDemo R2 = new RunnableDemo( "Thread-2");

R2.start();

}

}

Call the thread using the start () method

Invoke the start () method after creating a thread object to begin execution. This will trigger the JVM to run its run () method in a new thread.

void start( );

Create a thread by extending the thread class

class ThreadDemo extends Thread {

private Thread t;

private String threadName;

ThreadDemo( String name) {

threadName = name;

System.out.println("Creating " + threadName );

}

public void run() {

System.out.println("Running " + threadName );

try {

for(int i = 4; i > 0; i--) {

System.out.println("Thread: " + threadName + ", " + i);

// Let the thread sleep for a while.

Thread.sleep(50);

}

} catch (InterruptedException e) {

System.out.println("Thread " + threadName + " interrupted.");

}

System.out.println("Thread " + threadName + " exiting.");

}

public void start () {

System.out.println("Starting " + threadName );

if (t == null) {

t = new Thread (this, threadName);

t.start ();

}

}

}

public class TestThread {

public static void main(String args[]) {

ThreadDemo T1 = new ThreadDemo( "Thread-1");

T1.start();

ThreadDemo T2 = new ThreadDemo( "Thread-2");

T2.start();

}

}

Want to Learn Everything About Java Programming?

Boost your coding skills and gain hands-on knowledge in Java.

Explore Now

Conclusion

Multithreading in Java is more than just a programming technique. It's a gateway to building high-performance, responsive, and scalable applications. By allowing multiple threads to run concurrently, Java enables developers to fully utilize multi-core processors, leading to improved application performance and responsiveness.

FAQs: What is Multithreading in Java

Q1. What is the Difference Between the start() and run() Methods in Java?

In Java, the start() method is used to initiate a new thread of execution, while the run() method contains the code that constitutes the new thread's task. Calling start() invokes the run() method in a new thread; however, directly invoking run() does not start a new thread but executes the run() method in the current thread. Therefore, to achieve multithreading, it's essential to call start() rather than run() directly.

Q2. What Is the Difference Between a Process and a Thread?

A process is an independent program that runs in its own memory space, while a thread is a lightweight subprocess within a process. Threads within the same process share the same memory space, allowing for efficient communication and resource sharing. This distinction is crucial for understanding how multithreading optimizes performance by enabling concurrent execution within a single application.

Q3. What is Multithreading in Java used for?

Multithreading in Java is used to run multiple tasks at the same time, improving performance, responsiveness, and efficient use of CPU resources.

Q4. Why is Multithreading in Java important?

It improves performance, allows concurrent execution, and enhances responsiveness in applications.

Q5. How do you implement Multithreading in Java?

You can implement it by extending the Thread class or implementing the Runnable interface.

Q6. Why is synchronization needed in Java multithreading?

Synchronization prevents multiple threads from accessing shared data at the same time, avoiding errors.

About the Author
Author Nehal Sharma
About the Author

Nehal Sharma is a skilled content writer with expertise in Java, mobile development, and data analytics. She transforms complex data into actionable insights and has experience in business intelligence, data science, and Salesforce. She also simplifies technical concepts into clear, engaging content for learners and professionals.

Drop Us a Query
Fields marked * are mandatory
×

Your Shopping Cart


Your shopping cart is empty.