Java Multithreading Practice Questions with Solutions

Java Multithreading is a feature that allows a program to execute multiple tasks simultaneously. Instead of running one task at a time, multiple threads can work concurrently, improving application performance and responsiveness.

A thread is the smallest unit of execution inside a Java program. Every Java application has at least one thread called the Main Thread. Java Multithreading practice questions with solutions help to understand the concepts.

Multithreading is widely used in modern applications such as:

  • Banking Systems
  • Online Gaming
  • Chat Applications
  • Video Streaming Platforms
  • Android Applications
  • Spring Boot Applications
  • Web Servers
  • File Download Managers

Why Do We Need Multithreading?

Multithreading helps developers:

  • Execute multiple tasks simultaneously
  • Improve CPU utilization
  • Increase application performance
  • Build responsive user interfaces
  • Perform background operations without freezing the application

For example:

  • Downloading files while browsing a website
  • Playing music while editing a document
  • Running multiple user requests on a web server

What is a Thread?

A Thread is a lightweight subprocess that executes independently within a Java application.

Each thread has its own:

  • Execution path
  • Program counter
  • Stack memory

Threads share:

  • Heap memory
  • Objects
  • Resources

Ways to Create a Thread in Java

Java provides two ways to create threads:

1. Extending the Thread Class

class MyThread extends Thread {

    public void run() {

        System.out.println("Thread Running");

    }

}

2. Implementing the Runnable Interface

class MyThread implements Runnable {

    public void run() {

        System.out.println("Thread Running");

    }

}

Thread Lifecycle

A Java thread passes through different states during execution.

New
 ↓
Runnable
 ↓
Running
 ↓
Blocked / Waiting
 ↓
Terminated

Advantages of Multithreading

  • Better Performance
  • Efficient CPU Utilization
  • Faster Execution
  • Improved User Experience
  • Background Processing
  • Parallel Task Execution

Real-World Applications

Multithreading is commonly used in:

  • Banking Software
  • Online Shopping Websites
  • Web Servers
  • Mobile Applications
  • Video Streaming Platforms
  • Multiplayer Games
  • Chat Applications
  • Desktop Software

Before Learning This Chapter

You should already understand:

  • Classes
  • Objects
  • Methods
  • Exception Handling
  • Collections Framework

1. Java Program to Create a Thread by Extending the Thread Class

Problem Statement

Write a Java program to create a thread by extending the Thread class.

Java Solution

class MyThread extends Thread {

    public void run() {

        System.out.println("Thread is Running");

    }

}

public class Main {

    public static void main(String[] args) {

        MyThread thread = new MyThread();

        thread.start();

    }

}

Sample Output

Thread is Running

Explanation

The program creates a new thread by extending the Thread class.

The run() method contains the task to be executed.

The start() method starts a new thread and automatically calls the run() method.

Concepts Covered

  • Thread Class
  • run()
  • start()
  • Multithreading

2. Java Program to Create a Thread Using the Runnable Interface

Problem Statement

Write a Java program to create a thread using the Runnable interface.

Java Solution

class MyThread implements Runnable {

    public void run() {

        System.out.println("Runnable Thread Running");

    }

}

public class Main {

    public static void main(String[] args) {

        MyThread task = new MyThread();

        Thread thread = new Thread(task);

        thread.start();

    }

}

Sample Output

Runnable Thread Running

Explanation

The Runnable interface provides greater flexibility because Java supports multiple interface implementation but does not support multiple inheritance.

This is the preferred approach for creating threads in real-world applications.

Concepts Covered

  • Runnable Interface
  • Thread Object
  • start()
  • run()

3. Java Program to Execute Multiple Threads

Problem Statement

Write a Java program to execute two threads simultaneously.

Java Solution

class ThreadOne extends Thread {

    public void run() {

        System.out.println("Thread One");

    }

}

class ThreadTwo extends Thread {

    public void run() {

        System.out.println("Thread Two");

    }

}

public class Main {

    public static void main(String[] args) {

        ThreadOne t1 = new ThreadOne();

        ThreadTwo t2 = new ThreadTwo();

        t1.start();

        t2.start();

    }

}

Sample Output

Thread One
Thread Two

Note: The execution order may vary because threads run independently.

Explanation

Both threads execute independently.

The operating system scheduler decides which thread executes first.

Concepts Covered

  • Multiple Threads
  • Thread Scheduling
  • Concurrent Execution
  • Thread Class

4. Java Program to Display Thread Name

Problem Statement

Write a Java program to display the name of a thread.

Java Solution

class MyThread extends Thread {

    public void run() {

        System.out.println("Thread Name : " + getName());

    }

}

public class Main {

    public static void main(String[] args) {

        MyThread thread = new MyThread();

        thread.setName("Java Worker Thread");

        thread.start();

    }

}

Sample Output

Thread Name : Java Worker Thread

Explanation

Every thread in Java has a unique name.

The setName() method changes the thread’s name, while getName() returns the current thread name.

Naming threads makes debugging and monitoring easier in large applications.

Concepts Covered

  • Thread Class
  • setName()
  • getName()
  • Thread Identification

5. Java Program to Display the Current Thread

Problem Statement

Write a Java program to display the currently executing thread.

Java Solution

public class Main {

    public static void main(String[] args) {

        Thread current = Thread.currentThread();

        System.out.println("Current Thread : " + current.getName());

    }

}

Sample Output

Current Thread : main

Explanation

The static method Thread.currentThread() returns a reference to the thread currently executing the code.

Since the program runs inside the main method, the current thread is the main thread.

This method is commonly used for:

  • Debugging
  • Logging
  • Monitoring thread execution

Concepts Covered

  • currentThread()
  • Main Thread
  • Thread Class
  • getName()

6. Java Program to Demonstrate Thread.sleep()

Problem Statement

Write a Java program to pause a thread for two seconds using the Thread.sleep() method.

Java Solution

public class Main {

    public static void main(String[] args) {

        try {

            System.out.println("Task Started");

            Thread.sleep(2000);

            System.out.println("Task Completed");

        }

        catch (InterruptedException exception) {

            System.out.println(exception);

        }

    }

}

Sample Output

Task Started

(2-second delay)

Task Completed

Explanation

The Thread.sleep() method temporarily pauses the execution of the current thread.

Thread.sleep(2000);

The value 2000 represents 2000 milliseconds, which equals 2 seconds.

Since sleep() can throw an InterruptedException, it must be enclosed in a try-catch block or declared using throws.

Concepts Covered

  • Thread.sleep()
  • InterruptedException
  • Thread Delay
  • Exception Handling

7. Java Program to Demonstrate Thread.join()

Problem Statement

Write a Java program to wait for one thread to finish before executing another.

Java Solution

class MyThread extends Thread {

    public void run() {

        System.out.println("Thread Executing");

    }

}

public class Main {

    public static void main(String[] args) {

        try {

            MyThread thread = new MyThread();

            thread.start();

            thread.join();

            System.out.println("Main Thread Finished");

        }

        catch (InterruptedException exception) {

            System.out.println(exception);

        }

    }

}

Sample Output

Thread Executing
Main Thread Finished

Explanation

The join() method makes the current thread wait until the specified thread finishes execution.

Without join(), the main thread may complete before the child thread.

It is commonly used when one task depends on the completion of another.

Concepts Covered

  • Thread.join()
  • Thread Synchronization
  • Waiting for Threads
  • InterruptedException

8. Java Program to Set Thread Priority

Problem Statement

Write a Java program to set and display the priority of a thread.

Java Solution

class MyThread extends Thread {

    public void run() {

        System.out.println("Thread Priority : " + getPriority());

    }

}

public class Main {

    public static void main(String[] args) {

        MyThread thread = new MyThread();

        thread.setPriority(Thread.MAX_PRIORITY);

        thread.start();

    }

}

Sample Output

Thread Priority : 10

Explanation

Java allows thread priorities from 1 to 10.

Available constants:

Thread.MIN_PRIORITY      // 1
Thread.NORM_PRIORITY     // 5
Thread.MAX_PRIORITY      // 10

Thread priority is only a suggestion to the operating system scheduler. The JVM does not guarantee that higher-priority threads will always execute first.

Concepts Covered

  • Thread Priority
  • MAX_PRIORITY
  • MIN_PRIORITY
  • NORM_PRIORITY

9. Java Program to Check Whether a Thread Is Alive

Problem Statement

Write a Java program to check whether a thread is currently running.

Java Solution

class MyThread extends Thread {

    public void run() {

        System.out.println("Thread Running");

    }

}

public class Main {

    public static void main(String[] args) {

        MyThread thread = new MyThread();

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

        thread.start();

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

    }

}

Sample Output

false
true
Thread Running

Note: Depending on system timing, the second isAlive() call may occasionally print false if the thread finishes very quickly.

Explanation

The isAlive() method checks whether a thread has been started and is still executing.

It returns:

  • true → Thread is running.
  • false → Thread has not started or has already finished.

Concepts Covered

  • isAlive()
  • Thread Status
  • Thread Lifecycle
  • Multithreading

10. Java Program to Create Multiple Runnable Threads

Problem Statement

Write a Java program to create and execute multiple threads using the Runnable interface.

Java Solution

class Task implements Runnable {

    public void run() {

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

    }

}

public class Main {

    public static void main(String[] args) {

        Task task = new Task();

        Thread thread1 = new Thread(task);

        Thread thread2 = new Thread(task);

        thread1.setName("Thread One");

        thread2.setName("Thread Two");

        thread1.start();

        thread2.start();

    }

}

Sample Output

Thread One
Thread Two

Note: The execution order is not fixed and may vary because thread scheduling is controlled by the JVM and operating system.

Explanation

Both threads execute the same Runnable task independently.

Using the Runnable interface is preferred because:

  • It promotes better code reusability.
  • It allows a class to extend another class while still supporting multithreading.

Concepts Covered

  • Runnable Interface
  • Multiple Threads
  • Thread Naming
  • Concurrent Execution

11. Java Program to Synchronize Threads Using the synchronized Keyword

Problem Statement

Write a Java program to synchronize multiple threads using the synchronized keyword.

Java Solution

class Counter {

    private int count = 0;

    public synchronized void increment() {

        count++;

        System.out.println("Count : " + count);

    }

}

class MyThread extends Thread {

    Counter counter;

    MyThread(Counter counter) {

        this.counter = counter;

    }

    public void run() {

        counter.increment();

    }

}

public class Main {

    public static void main(String[] args) {

        Counter counter = new Counter();

        MyThread t1 = new MyThread(counter);

        MyThread t2 = new MyThread(counter);

        t1.start();

        t2.start();

    }

}

Sample Output

Count : 1
Count : 2

Explanation

The synchronized keyword allows only one thread to execute the method at a time.

Without synchronization, multiple threads may modify shared data simultaneously, leading to inconsistent results known as race conditions.

Concepts Covered

  • synchronized Keyword
  • Shared Resources
  • Thread Safety
  • Race Condition Prevention

12. Java Program to Demonstrate Thread Synchronization

Problem Statement

Write a Java program to demonstrate synchronization while printing messages.

Java Solution

class Printer {

    public synchronized void print(String message) {

        for (int i = 1; i <= 3; i++) {

            System.out.println(message);

        }

    }

}

class MyThread extends Thread {

    Printer printer;
    String message;

    MyThread(Printer printer, String message) {

        this.printer = printer;
        this.message = message;

    }

    public void run() {

        printer.print(message);

    }

}

public class Main {

    public static void main(String[] args) {

        Printer printer = new Printer();

        MyThread t1 = new MyThread(printer, "Java");

        MyThread t2 = new MyThread(printer, "Python");

        t1.start();

        t2.start();

    }

}

Sample Output

Java
Java
Java
Python
Python
Python

Note: Because the method is synchronized, one thread finishes printing before the other enters the method.

Explanation

Synchronization prevents both threads from executing the print() method simultaneously, ensuring clean and predictable output.

Concepts Covered

  • synchronized Method
  • Shared Object
  • Thread Coordination
  • Thread Safety

13. Java Program for Inter-thread Communication Using wait() and notify()

Problem Statement

Write a Java program to demonstrate basic inter-thread communication using wait() and notify().

Java Solution

class Message {

    synchronized void printMessage() {

        try {

            System.out.println("Waiting...");

            wait();

            System.out.println("Thread Resumed");

        }

        catch (InterruptedException exception) {

            System.out.println(exception);

        }

    }

    synchronized void sendNotification() {

        System.out.println("Notification Sent");

        notify();

    }

}

public class Main {

    public static void main(String[] args) {

        Message message = new Message();

        Thread t1 = new Thread(() -> message.printMessage());

        Thread t2 = new Thread(() -> message.sendNotification());

        t1.start();

        t2.start();

    }

}

Sample Output

Waiting...
Notification Sent
Thread Resumed

Note: Due to thread scheduling, the exact order may vary. The waiting thread must call wait() before another thread calls notify() for this demonstration to behave as shown.

Explanation

  • wait() pauses the current thread.
  • notify() wakes one waiting thread.

These methods are used for communication between threads sharing the same object.

Concepts Covered

  • wait()
  • notify()
  • Thread Communication
  • Synchronization

14. Java Program to Demonstrate a Producer-Consumer Example

Problem Statement

Write a simple Java program that demonstrates the Producer-Consumer concept using threads.

Java Solution

class Resource {

    synchronized void produce() {

        System.out.println("Item Produced");

    }

    synchronized void consume() {

        System.out.println("Item Consumed");

    }

}

public class Main {

    public static void main(String[] args) {

        Resource resource = new Resource();

        Thread producer = new Thread(() -> resource.produce());

        Thread consumer = new Thread(() -> resource.consume());

        producer.start();

        consumer.start();

    }

}

Sample Output

Item Produced
Item Consumed

Explanation

This simplified example demonstrates the Producer-Consumer pattern.

In real-world applications, producers generate data while consumers process that data.

Examples include:

  • Order Processing Systems
  • Banking Applications
  • Message Queues
  • Inventory Management
  • Streaming Platforms

Concepts Covered

  • Producer Thread
  • Consumer Thread
  • Synchronization
  • Concurrent Programming

15. Java Program to Build a Real-World Ticket Booking System Using Multithreading

Problem Statement

Write a Java program to simulate a simple ticket booking system where multiple users attempt to book tickets.

Java Solution

class TicketCounter {

    private int tickets = 3;

    public synchronized void bookTicket(String name) {

        if (tickets > 0) {

            System.out.println(name + " booked Ticket " + tickets);

            tickets--;

        }

        else {

            System.out.println(name + " : Tickets Sold Out");

        }

    }

}

class BookingThread extends Thread {

    TicketCounter counter;
    String customer;

    BookingThread(TicketCounter counter, String customer) {

        this.counter = counter;
        this.customer = customer;

    }

    public void run() {

        counter.bookTicket(customer);

    }

}

public class Main {

    public static void main(String[] args) {

        TicketCounter counter = new TicketCounter();

        new BookingThread(counter, "Rahul").start();

        new BookingThread(counter, "Amit").start();

        new BookingThread(counter, "Neha").start();

        new BookingThread(counter, "Priya").start();

    }

}

Sample Output

Rahul booked Ticket 3
Amit booked Ticket 2
Neha booked Ticket 1
Priya : Tickets Sold Out

Note: The booking order may vary because thread execution depends on the scheduler.

Explanation

The bookTicket() method is synchronized to ensure that only one customer books a ticket at a time.

Without synchronization, multiple threads could reduce the ticket count simultaneously, causing incorrect bookings.

This pattern is commonly used in:

  • Railway Reservation Systems
  • Flight Booking Applications
  • Movie Ticket Booking Systems
  • Event Registration Platforms

Concepts Covered

  • Multithreading
  • synchronized
  • Shared Resource
  • Real-World Concurrency
  • Ticket Booking Simulation

Chapter Summary

In this chapter, you learned the fundamentals of Java Multithreading, one of the most important topics in Core Java. Multithreading enables a Java application to perform multiple tasks concurrently, resulting in better performance, improved responsiveness, and efficient CPU utilization.

You explored different ways to create threads, manage thread execution, synchronize shared resources, and enable communication between threads. You also implemented real-world examples such as ticket booking systems and producer-consumer models to understand how multithreading is applied in modern software development.

Throughout this chapter, you covered:

  • Introduction to Multithreading
  • Thread Class
  • Runnable Interface
  • Creating Threads
  • Multiple Threads
  • Thread Naming
  • Current Thread
  • Thread.sleep()
  • Thread.join()
  • Thread Priority
  • isAlive()
  • synchronized Keyword
  • Thread Synchronization
  • wait() and notify()
  • Producer-Consumer Example
  • Ticket Booking System

These concepts are essential for developing scalable desktop applications, Android apps, enterprise software, and high-performance web applications.


Key Takeaways

  • A thread is the smallest unit of execution in Java.
  • Every Java application starts with the main thread.
  • Threads can be created by extending the Thread class or implementing the Runnable interface.
  • The Runnable interface is generally preferred because it supports better code reusability.
  • Thread.sleep() pauses thread execution for a specified time.
  • Thread.join() waits for another thread to complete before continuing.
  • Thread priorities influence scheduling but do not guarantee execution order.
  • The synchronized keyword prevents race conditions by allowing only one thread to access shared resources at a time.
  • wait() and notify() provide communication between threads.
  • Multithreading is widely used in real-world systems requiring concurrent task execution.

Frequently Asked Questions (FAQs)

1. What is Multithreading in Java?

Multithreading is the ability of a Java program to execute multiple threads simultaneously, allowing several tasks to run concurrently.


2. What is the difference between a Process and a Thread?

ProcessThread
Independent programSmallest execution unit inside a process
Has separate memoryShares memory with other threads
HeavyweightLightweight
Slower communicationFaster communication

3. What are the two ways to create a thread in Java?

Java provides two common approaches:

  • Extending the Thread class
  • Implementing the Runnable interface

The Runnable interface is generally recommended because it supports better object-oriented design.


4. What is the purpose of the start() method?

The start() method creates a new thread and invokes the run() method automatically.

Example:

MyThread thread = new MyThread();
thread.start();

Calling run() directly does not create a new thread; it executes like a normal method.


5. What is Thread Synchronization?

Thread synchronization ensures that only one thread accesses a shared resource at a time, preventing inconsistent results.

It is implemented using the synchronized keyword.


6. What is the purpose of Thread.sleep()?

Thread.sleep() pauses the execution of the current thread for a specified amount of time.

Example:

Thread.sleep(1000);

This pauses the thread for 1000 milliseconds (1 second).


7. What are wait() and notify() used for?

These methods are used for inter-thread communication.

  • wait() pauses a thread until it receives a notification.
  • notify() wakes up one waiting thread.

They must be called inside synchronized methods or synchronized blocks.


8. Where is Java Multithreading used in real-world applications?

Java Multithreading is widely used in:

  • Banking Systems
  • Online Ticket Booking
  • Chat Applications
  • Android Apps
  • Spring Boot Applications
  • Multiplayer Games
  • Video Streaming Platforms
  • Web Servers
  • File Download Managers
  • E-commerce Platforms

Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.

Scroll to Top