Top 10 Multithreading Interview Questions in Java
Multithreading is fundamental in Java for building highly scalable and efficient applications. By enabling multiple threads to run concurrently, it offers significant performance improvements. However, mastering its concepts requires understanding its intricacies and the tools Java provides for handling concurrent programming.
This post provides a comprehensive guide to the Top 10 Multithreading Interview Questions that candidates should prepare for in 2025. With detailed answers, practical examples, and links to resources, this guide will equip you to handle even the most challenging interview scenarios.
Table of Contents
- What is the Difference Between Thread and Runnable?
- Explain Synchronized Keyword and Its Limitations
- What is a Deadlock and How to Avoid It?
- Difference Between wait() and sleep()
- What is Thread Starvation?
- What is the Use of Volatile Keyword?
- How to Create a Custom Thread Pool?
- Daemon Thread vs User Thread
- Thread Lifecycle and States
- Real-World Scenario: Implementing a Worker Thread Pool
1. What is the Difference Between Thread and Runnable?
Java provides two ways to define and execute tasks concurrently — via the Thread
class or by implementing the Runnable
interface. Understanding their differences is critical.
| Thread | Runnable |
|———————————————|———————————————|
| Extends the Thread
class. | Implements the Runnable
interface. |
| Cannot inherit from other classes due to single inheritance. | Can inherit from other classes. |
| Logic is defined by overriding the run()
method. | Logic is implemented by overriding the run()
method. |
Example Using Thread
class MyThread extends Thread { @Override public void run() { System.out.println("Thread is running."); } } public class Example { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); } }
Example Using Runnable
class MyRunnable implements Runnable { @Override public void run() { System.out.println("Runnable is running."); } } public class Example { public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); } }
Key Takeaway: While both approaches are valid, the Runnable
interface is preferred for better design flexibility and code reusability.
Learn more about Thread vs Runnable
2. Explain Synchronized Keyword and Its Limitations
The synchronized keyword in Java defines critical sections, ensuring thread safety by allowing only one thread to access the synchronized block or method.
Example
public class SynchronizedExample { private int count = 0; public synchronized void increment() { count++; } public synchronized int getCount() { return count; } }
Limitations
- Performance Overhead – When multiple threads contend for the same lock, application performance may degrade.
- No Fair Locking – Threads waiting for synchronization are not guaranteed prioritized access.
- Potential Deadlocks – Incorrect synchronization can lead to threads waiting indefinitely.
3. What is a Deadlock and How to Avoid It?
A deadlock happens when two threads are mutually waiting for each other to release resources, blocking further execution.
Example of Deadlock
public class DeadlockExample { private final Object lock1 = new Object(); private final Object lock2 = new Object(); public void methodA() { synchronized (lock1) { synchronized (lock2) { System.out.println("Method A is executing."); } } } public void methodB() { synchronized (lock2) { synchronized (lock1) { System.out.println("Method B is executing."); } } } }
Avoiding Deadlock
- Always acquire locks in a consistent order.
- Use
tryLock()
to specify a timeout, ensuring threads don’t wait indefinitely.
4. Difference Between wait() and sleep()
| Feature | wait() | sleep() |
|————————–|——————————-|———————————|
| Belongs to | Object
class. | Thread
class. |
| Lock Behavior | Temporarily releases the lock it holds. | Retains its lock during execution. |
| Usage | Must be called within a synchronized block. | Can be invoked anywhere. |
Example of wait()
synchronized(lock) { lock.wait(); lock.notify(); }
5. What is Thread Starvation?
Thread starvation occurs when low-priority threads are unable to gain access to resources due to the dominance of higher-priority threads.
How to Prevent Starvation
- Use fair locks, such as
ReentrantLock
with a fairness policy. - Avoid giving higher priority to threads unnecessarily.
6. What is the Use of Volatile Keyword?
The volatile
keyword ensures that a variable’s updates are directly visible to all threads by bypassing thread-local caching.
Example:
private static volatile boolean active = true; public static void main(String[] args) { new Thread(() -> { while (active) { // Running } }).start(); active = false; }
7. How to Create a Custom Thread Pool?
Java allows creation of custom thread pools using the ThreadPoolExecutor
class.
Example:
ExecutorService executor = new ThreadPoolExecutor( 3, 5, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>() ); executor.execute(() -> System.out.println("Task is running."));
Learn more about ThreadPoolExecutor
8. Daemon Thread vs User Thread
| Aspect | Daemon Thread | User Thread |
|————————-|——————————|———————————|
| Role | Executes background tasks. | Drives application logic. |
9. Thread Lifecycle and States
Java threads have six states:
- NEW
- RUNNING
- BLOCKED
- WAITING
- TIMED_WAITING
- TERMINATED
Example:
Thread thread = new Thread(() -> {}); System.out.println(thread.getState()); // NEW thread.start();
10. Real-World Scenario: Implementing a Worker Thread Pool
public class WorkerThread implements Runnable { private final String task; public WorkerThread(String task) { this.task = task; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " executing " + task); } public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(4); for (int i = 0; i < 10; i++) { executor.submit(new WorkerThread("Task " + i)); } executor.shutdown(); } }
FAQs
What is yield()?
The yield()
method suggests the thread scheduler pause the current thread, allowing others to execute.
How do you debug multithreading issues?
Use thread dump analysis, logging tools, or performance profilers like VisualVM or JProfiler.
Summary
Mastering multithreading in Java requires a combination of theoretical knowledge and practical skills. Understanding concepts such as synchronization, thread safety, and concurrency tools will not only shine in interviews but also help in building robust applications. Keep practicing with the above examples to develop a deeper comprehension of these principles!