Java Multithreading Interview Questions and Answers 2024

Java Multithreading Interview Questions and Answers 2024

13 Sep 2024
Question
2.02K Views
51 min read
Learn via Video Course & by Doing Hands-on Labs

Java Online Course Free with Certificate (2024)

Java Multithreading Interview Questions

Multithreading in Java stands out as a critical component for developers aiming to demonstrate their Java expertise. If Java is your preferred language for your software engineer interview, these Java Multithreading Interview Questions will give you an idea of the questions you will face in your interview. So don't miss out on this.

Our experts have crafted these interview questions based on a real-time analysis of the questions commonly asked in technical rounds today. The complexity of the questions is gradually moving from basic thread concepts to advanced concepts like context switching. It will help you build your concepts level by level.

Gain the skills employers are looking for with our Java Full Stack Developer Certification Training—don’t miss out.

Java Multithreading Interview Questions for Freshers

1. What is multithreading?

It is a process of concurrently executing multiple threads or parts of a program. Multithreading is used for multitasking purposes. It acquires less memory and provides fast and efficient performance.

2. What is the thread?

A thread is nothing but a lightweight subprocess. It is a different path of execution. Every thread runs in a different stack frame. The process can contain multiple threads. Every thread shares the same memory space.

3. Differentiate between process and thread.

Differentiate between process and thread.

ProcessThread
A program in execution is a processThread is a part of a process
Processes are heavyweightThreads are lightweight
Termination is slowTermination is fast
Creation takes timeCreation takes less time
Communication between processes needs more timeCommunication between threads requires less time
More time for context-switchingLess time for context-switching
Processes do not share memoryThreads share memory
Consumes more resourcesConsumes lesser resources

4. What is inter-thread communication?

  • Inter-thread communication is nothing but the process of communication between synchronized threads.
  • It is used to avoid thread polling in Java.
  • The thread is paused running in its critical section, and another thread is allowed to enter the same critical section to be executed.
  • inter-thread communication can be achieved by wait(), notify(), and notifyAll() methods.

What is inter-thread communication?

5. Explain wait() method in Java? Why must it be called from the synchronized block?

It is the method provided by the Object class in Java. It is used for inter-thread communication in Java. java. lang.Object. wait() method is used to pause the current thread and wait until another thread does not call the notify() or notifyAll() method.

Syntax

 public final void wait()

We have to call the wait() method otherwise it will throw java.lang.IllegalMonitorStateException type exception. Because of this, we need the wait() method for inter-thread communication with notify() and notifyAll() methods.

6. How will you synchronize a method in Java?

We can use the synchronized modifier in the method's signature or use the synchronized {} construct inside the method.

Example


   public void swap()
   {
       synchronized (this)
       {
       //Code
       }
   }

   public synchronized void swap1EqualsSwap()
   {
   //Code
   }

   public static synchronized void swap2()
   {
   //Code
   }

   public static void swap3EqualsSwap2()
   {
       synchronized (JoinClass.class)
       {
           //Code
       }
   }

7. What are the advantages of multithreading?

  • Improved Performance: Multithreaded programs can use multi-core processors, making them faster and more efficient.
  • Enhanced Responsiveness: Multithreading allows for responsive user interfaces (UIs) in applications. Long-running tasks can be moved to background threads, ensuring the UI remains responsive to user input.
  • Resource Utilization: Multithreading enables better utilization of system resources, as different threads can execute different tasks simultaneously.
  • Parallel Processing: Multithreading is essential for parallel processing, where a large task is divided into smaller sub-tasks that can be executed concurrently, reducing overall execution time.

What are some fundamental advantages of multithreading in Java?

8. Discuss the states in the lifecycle of a Thread.

  • New: A Thread class object is created using a new operator, but the thread is not alive. The thread doesn't start until we call the start() method.
  • Runnable: The thread is run after calling the start() method. It is waiting in the ready or runnable queue to be allocated to the processor.
  • Running: In this state, the thread scheduler picks the thread from the ready state and the thread executes.
  • Waiting/Blocked: In this state, a thread is not running but still alive, or waiting for the other thread to finish.
  • Dead/Terminated: The thread exits or stops executing due to some unusual happenings.

What are the states in the lifecycle of a Thread?

9. Explain the difference between preemptive scheduling and time slicing.

In preemptive scheduling, the highest priority task executes until it enters the waiting or dead state or a higher priority task comes into existence. On the other hand, in time slicing, a task executes for a predefined slice of time and then reenters the pool of ready tasks. Then the scheduler determines which task should execute next, based on priority and other factors.

Join ScholarHat’s Java Full-Stack program and start coding like a pro.

Training Name Price
Full-Stack Java Developer Course (Become Job-Ready with ₹3 - ₹9 LPA* Opportunities)Book a FREE Live Demo!

10. What is context switching?

Context Switching is the process/method used by the system to change the process from one state to another using the CPUs present in the system to perform its job. It allows a single CPU to handle multiple process requests parallelly without the need for any additional processors.

11. Differentiate between the Thread class and Runnable interface for creating a thread.

  • The thread can be created by extending the Thread class
  • The thread can be created by implementing the Runnable interface
Thread ClassRunnable Interface
It has multiple methods like start() and run()It has only abstract method run()
Each thread creates a unique object and gets associated with itMultiple threads share the same objects
More memory requiredLess memory required
Multiple Inheritance is not allowed in Java hence after a class extends the Thread class, it can not extend any other classIf a class implements the runnable interface, it can extend another class.

12. What is join() method?

One thread can call the join() method on another thread. As a result, the first thread that called the method suspends its work and waits for the second thread to finish execution.

The Thread class has three forms of join() method:

  1. public final void join() throws InterruptedException
  2. public final void join(long millis) throws InterruptedException
  3. public final void join(long millis, int nanos) throws InterruptedException

13. Describe the purpose and working of the sleep() method.

sleep() method in Java blocks a thread for a particular time, which means it pauses the execution of a thread for a specific time. There are two overloaded forms of sleep() method in java.lang.Thread class.

  1. public static void sleep(long millis) throws InterruptedException
  2. public static void sleep(long millis, int nanos) throws InterruptedException

Example Illustrating the Working of sleep() method


public class ThreadsInJava
{
    public static void main(String[] args)
    {
        System.out.println("Before Sleeping");
 
        try
        {
            Thread.sleep(50);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
 
        System.out.println("After Sleeping");
    }
}

Thread.sleep(50) pauses the execution of the current thread for 50 milliseconds.

Output

Before Sleeping
After Sleeping

14. List out the differences between wait() and sleep() method.

wait()sleep()
wait() is a method of Object classsleep() is a method of Thread class
wait() releases lock during synchronizationsleep() method does not release the lock on the object during synchronization
wait() is not a static method.sleep() is a static method
wait() has three overloaded methods:
  • wait()
  • wait(long timeout)
  • wait(long timeout, int nanos)
sleep() has two overloaded methods:
  • sleep(long millis)millis: milliseconds
  • sleep(long millis,int nanos) nanos: Nanoseconds

15.Can we call the run() method instead of start()?

  • Yes, calling the run() method directly is valid, but it will not work as a thread instead it will work as a normal object.
  • There is no context-switching between the threads.
  • When we call the start() method, it internally calls the run() method. It creates a new stack for a thread while directly calling the run() will not create a new stack.

16. Explain daemon threads.

  • JVM creates daemon threads.
  • They are the low-priority threads that provide the background support and services to the user threads.
  • JVM will not wait for these threads to finish their execution. JVM will exit as soon as all user threads finish their execution.
  • There are two methods for daemon thread available in the Thread class:
    1. public void setDaemon(boolean status) marks the thread as a daemon or a user thread.
    2. public boolean daemon () checks whether the thread is a daemon.

17. What are the two ways of implementing thread in Java?

1. Extending the Thread class

Example


class MultithreadingDemo extends Thread 
{   
  public void run() 
 {   
     System.out.println("Welcome to Scholarhat.");    
 } 
  public static void main(String args[]) 
 {   
    MultithreadingDemo obj=new MultithreadingDemo();  
        obj.start();  
  }  
} 
    

Output

Welcome to Scholarhat.   

2. Implementing Runnable interface in Java

Example


class MultithreadingDemo implements Runnable 
{  
   public void run() 
 {  
      System.out.println("Welcome to Scholarhat..");  
  }  
    public static void main(String args[]) 
 {  
      MultithreadingDemo obj=new MultithreadingDemo();   
      Threadtobj =new Thread(obj);       tobj.start();  
 }   
} 
    

Output

Welcome to Scholarhat.   

18.What’s the difference between notify() and notifyAll()?

1.notify()

  • It sends a notification and wakes up only a single thread instead of multiple threads that are waiting on the object’s monitor.
  • The notify() method is defined in the Object class, which is Java’s top-level class.
  • It’s used to wake up only one thread that’s waiting for an object, and that thread then begins execution.
  • The thread class notify() method is used to wake up a single thread.

notify():

2.notifyAll()

  • It sends notifications wakes up all threads and allows them to compete for the object's monitor instead of a single thread.
  • The notifyAll() wakes up all threads that are waiting on this object’s monitor.
  • A thread waits on an object’s monitor by calling one of the wait methods.
  • The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.

notifyAll()

19. What is the default priority of a thread? Can we change it?

The default priority of a thread is the same as that of its parent. Yes, we can change the priority of a thread at any time using the setPriority() method.

Example


public class ThreadPriority 
{
    public static void main(String[] args) 
    {
        Thread t = Thread.currentThread();
         
        System.out.println(t.getPriority());       
         
        t.setPriority(8);
         
        System.out.println(t.getPriority());      
    }
}
    

t.setPriority(8) sets the current thread priority to 8. By default, the priority of the main thread is Thread.NORM_PRIORITY, which is generally 5. This value is printed to the console.

Output

5 
8 

20. Is it possible to make constructors synchronized in Java?

No, the synchronized keyword cannot be used with constructors in Java. The synchronization mechanism in Java is designed to manage access to objects that already exist, ensuring that multiple threads do not interfere with each other when accessing a shared resource.

Java Multithreading Interview Questions for Intermediates

21. How interrupted() is different from isInterrupted() method in Java

interrupted()isInterrupted()
interrupted() is a static method of the Thread classisInterrupted() is an instance method of the Thread class
interrupted() clears the interrupted status of the current threadisInterrupted() method does not clear the interrupted status
operates on the currently executing threadcan be invoked on any Thread instance
It resets the interrupted status to falseisInterrupted() does not affect the interrupted status
can be invoked without a thread referencerequires a thread reference to invoke
checks the interrupted status of the current threadchecks the interrupted status of a specific thread

22. Can we call start() method twice?

No, we can call the start() method only once. If you call the start() method a second time, it will throw an IllegalThreadStateException as the thread has already started.

23. What is a ThreadGroup?

ThreadGroup is a set of threads that can also contain other groups of threads. A group of threads forms a tree in which every other group of threads has a parent (except the original one). A thread has the right to access data from its thread group but does not have such access to other groups or the parent group of threads.

24. Describe the race condition.

A race condition occurs when multiple concurrent threads compete to run first. If the thread that wins the race isn't the one that was supposed to run first, the code may exhibit unexpected behavior. Synchronization can resolve this issue.

25. What are the common problems faced while working with threads in Java?

  • Race Conditions: Thread interference leads to unexpected outcomes due to shared data access.
  • Deadlocks: Circular waiting of threads for resources, causing a standstill in execution.
  • Starvation: Unequal thread priority leads to some threads being consistently deprived of resources.
  • Thread Synchronization Issues: Inconsistent synchronization of threads causes unpredictable behavior.
  • Thread Safety Challenges: Ensuring data integrity across multiple threads can be complex.
  • Performance Overheads: Context switching and synchronization mechanisms may impact system performance.
  • Difficulty in Debugging: Identifying and rectifying thread-related issues can be difficult due to their asynchronous nature.
  • Complexity in Coordination: Coordinating multiple threads for efficient execution requires careful design.
  • Non-deterministic Execution: It can be difficult to predict the order of thread execution, leading to potential issues.
  • Resource Contention: Threads competing for shared resources, causing delays and inefficiencies.

26. What are thread-local variables in Java?

Thread-local variables in Java are variables local to each thread i.e. each thread has its own copy. These variables are declared with the ThreadLocal class. This helps in avoiding interference between threads by providing isolated data storage.

27. What is a monitor?

The monitor is a body of code that can be executed by only one thread at a time.If any other thread attempts to get access at the same time, it will be suspended until the current thread releases the Monitor. Monitor monitors the access control of shared resources and objects among threads. Using this construct only one thread at a time gets access control over the critical section at the resource.

28. What do you understand about Deadlock situations in Java Multithreading?

Deadlock is a situation where each thread is waiting for resources held by other waiting threads. Due to this situation, no threads are executed, causing a pause in program execution and breaking the code at runtime.

29. How do you detect deadlock situations in Java? How can they be avoided?

Deadlock situations can be detected by running the executable code on cmd and subsequently collecting the thread dump. If deadlock situations are present, the cmd will throw up a message on cmd.

To avoid deadlock situations in Java:

  • Avoid Nested Lock: This may create a deadlock if another thread wants the same lock currently held by this thread. Use lock ordering if you need nested synchronized blocks.
  • Avoid unnecessary locks: Specify the time for a thread to acquire the lock. It is called lock timeout. Lock the code where it is needed.

30. Why is thread behavior unpredictable?

This is because the execution of threads depends on the thread scheduler. One should remember that every thread scheduler has a different implementation on different platforms like Windows, Unix, etc.

31. What's the use of the volatile keyword in Java Multithreading?

The volatile keyword guarantees visibility and ordering of variable updates across threads. Any thread reading the variable sees the most recent modification made by any other thread when a variable is declared as volatile. It prevents compiler optimizations that reorder the code and ensures a consistent view of the shared variable among threads.

32. What is Thread Scheduler?

Thread Scheduler is a part of JVM. It decides which thread will execute next when multiple threads are waiting in the queue for their execution. It looks at the priority assigned to each READY thread and selects the next one to execute. For thread scheduling, the thread scheduler mainly uses two mechanisms:

  1. Preemptive Scheduling
  2. Time-slicing Scheduling

33. What is ThreadPool?

A thread pool in Java is a managed group of threads, providing a reusable pool of worker threads for executing tasks. It efficiently manages thread creation, execution, and termination, enhancing performance by minimizing thread creation overhead. This mechanism helps in better resource utilization and scalability in multithreaded applications.

34. How do you name the thread in Java?

We can name a thread by using the setName() method replacing default naming which was ‘Thread-0’, ‘Thread-1’, and so on.

Syntax


thread_class_object.setName("Name_thread_here");

35. Does each thread have its stack in multithreaded programming?

Yes, in multithreaded programming every thread maintains its own or separate stack area in memory due to which every thread is independent of each other.

Java Multithreading Interview Questions for Experienced

36. What is BlockingQueue?

  • BlockingQueue represents a thread-safe queue.
  • The producer thread inserts resource/element into the queue using the put() method unless it gets full and the consumer thread takes resources from the queue using the take() method until it gets empty.
  • But if a thread tries to dequeue from an empty queue, then a particular thread will be blocked until some other thread inserts an item into the queue, or if a thread tries to insert an item into a queue that is already full, then a particular thread will be blocked until some threads take away an item from the queue.
  • Synchronized Block: In this method, the thread acquires a lock on the object between parentheses after the synchronized keyword, and releases the lock when they leave the block. No other thread can acquire a lock on the locked object unless and until the synchronized block exists. It can be used when one wants to keep other parts of the programs accessible to other threads.
  • Synchronized blocks should be preferred more as it boost the performance of a particular program. It only locks a certain part of the program (critical section) rather than the entire method and therefore leads to less contention.

Example

 package org.arpit.java2blog; 
 
import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.BlockingQueue; 
 
public class BlockingQueuePCExample { 
 
   public static void main(String[] args) { 
 
       BlockingQueue queue=new ArrayBlockingQueue<>(5); 
       Producer producer=new Producer(queue); 
       Consumer consumer=new Consumer(queue); 
       Thread producerThread = new Thread(producer); 
       Thread consumerThread = new Thread(consumer); 
 
       producerThread.start(); 
       consumerThread.start(); 
 
   } 
 
   static class Producer implements Runnable { 
 
       BlockingQueue queue=null; 
 
       public Producer(BlockingQueue queue) { 
           super(); 
           this.queue = queue; 
       } 
 
       @Override 
       public void run() { 
 
               try { 
                   System.out.println("Producing element 1"); 
                   queue.put("Element 1"); 
                   Thread.sleep(1000); 
                   System.out.println("Producing element 2"); 
                   queue.put("Element 2"); 
                   Thread.sleep(1000); 
                   System.out.println("Producing element 3"); 
                   queue.put("Element 3"); 
               } catch (InterruptedException e) { 
 
                   e.printStackTrace(); 
               } 
       } 
   }  
   static class Consumer implements Runnable { 
 
       BlockingQueue queue=null; 
 
       public Consumer(BlockingQueue queue) { 
           super(); 
           this.queue = queue; 
       } 
 
       @Override 
       public void run() { 
 
           while(true) 
           { 
               try { 
                   System.out.println("Consumed "+queue.take()); 
               } catch (InterruptedException e) { 
                   e.printStackTrace(); 
               } 
           } 
       } 
 
   } 
}    

Output

Producing element 1 
Consumed Element 1 
Producing element 2 
Consumed Element 2 
Producing element 3 
Consumed Element 3   

37. What is the difference between `synchronized` and `Lock` in Java?

The `synchronized` keyword automatically locks an object or method while the `Lock` interface, from the `java.util.concurrent` package offers locking options. With a lock you can use features, like try locking, timed locking and interruptible locking for flexibility in managing locks.
 import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

   public class LockExample {
       private final Lock lock = new ReentrantLock();

       public void method() {
           lock.lock();
           try {
               // critical section
               System.out.println("Locked method execution");
           } finally {
               lock.unlock();
           }
       }
   }

38. How do you create a thread-safe singleton class using the Bill Pugh Singleton design?

When you implement the Bill Pugh Singleton Design you utilize an helper class to store the Singleton instance. The creation of the Singleton instance occurs when the inner class is loaded.
 public class Singleton {
       private Singleton() {}

       private static class SingletonHelper {
           private static final Singleton INSTANCE = new Singleton();
       }

       public static Singleton getInstance() {
           return SingletonHelper.INSTANCE;
       }
   } 

39. What is the difference between `wait()` and `sleep()` in Java?

The `wait()` method is used with an object to release the lock held by the thread and wait until another thread invokes either `notify()` or `notifyAll()` on the object. On the hand the `sleep()` method, which is a method of the `Thread` class pauses the current threads execution, for a specific period, without releasing the lock.
 public class WaitSleepExample {
       public static void main(String[] args) {
           final Object lock = new Object();

           Thread t1 = new Thread(() -> {
               synchronized (lock) {
                   try {
                       System.out.println("Thread 1 waiting");
                       lock.wait();
                       System.out.println("Thread 1 resumed");
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
           });

           Thread t2 = new Thread(() -> {
               synchronized (lock) {
                   try {
                       System.out.println("Thread 2 sleeping");
                       Thread.sleep(1000);
                       System.out.println("Thread 2 awake and notifying");
                       lock.notify();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
           });

           t1.start();
           t2.start();
       }
   }  

40. Explain the `volatile` keyword in Java.

In Java the 'volatile' keyword is employed to designate a variable as stored in the memory. This guarantees that each reading and writing action occurs directly to and, from the memory thereby maintaining the visibility of changes, among threads.
 public class VolatileExample {
       private static volatile boolean flag = true;

       public static void main(String[] args) {
           Thread t1 = new Thread(() -> {
               while (flag) {
                   // Do some work
               }
               System.out.println("Thread 1 stopped.");
           });

           Thread t2 = new Thread(() -> {
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               flag = false;
               System.out.println("Flag set to false by Thread 2.");
           });

           t1.start();
           t2.start();
       }
   }

41. What is the difference between `Callable` and `Runnable` in Java?

A Runnable is a type of interface that includes a run method without a return value and no ability to throw a checked exception. On the hand a Callable is an interface, with a call method that can return a value and may throw a checked exception.
   import java.util.concurrent.Callable;
   import java.util.concurrent.ExecutionException;
   import java.util.concurrent.ExecutorService;
   import java.util.concurrent.Executors;
   import java.util.concurrent.Future;

   public class CallableExample {
       public static void main(String[] args) {
           ExecutorService executor = Executors.newSingleThreadExecutor();

           Callable task = () -> {
               Thread.sleep(500);
               return 123;
           };

           Future future = executor.submit(task);
           try {
               Integer result = future.get();
               System.out.println("Result: " + result);
           } catch (InterruptedException | ExecutionException e) {
               e.printStackTrace();
           } finally {
               executor.shutdown();
           }
       }
   }

42. Explain the `CountDownLatch` class.

A CountDownLatch is a tool, for tasks enabling one or more threads to pause until a series of actions, in threads finish.
   import java.util.concurrent.CountDownLatch;

   public class CountDownLatchExample {
       public static void main(String[] args) {
           int numberOfThreads = 3;
           CountDownLatch latch = new CountDownLatch(numberOfThreads);

           for (int i = 0; i < numberOfThreads; i++) {
               new Thread(new Worker(latch)).start();
           }

           try {
               latch.await();
               System.out.println("All threads finished execution.");
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }

       static class Worker implements Runnable {
           private final CountDownLatch latch;

           Worker(CountDownLatch latch) {
               this.latch = latch;
           }

           @Override
           public void run() {
               try {
                   Thread.sleep(1000); // Simulate work
                   System.out.println(Thread.currentThread().getName() + " finished work.");
               } catch (InterruptedException e) {
                   e.printStackTrace();
               } finally {
                   latch.countDown();
               }
           }
       }
   }

43. What is the `ForkJoinPool` in Java?

ForkJoinPool is a version of ExecutorService created for handling tasks that can be divided into parts and run simultaneously.
 
   import java.util.concurrent.ForkJoinPool;
   import java.util.concurrent.RecursiveTask;

   public class ForkJoinExample {
       static class Fibonacci extends RecursiveTask {
           final int n;

           Fibonacci(int n) {
               this.n = n;
           }

           @Override
           protected Integer compute() {
               if (n <= 1) return n;
               Fibonacci f1 = new Fibonacci(n - 1);
               f1.fork();
               Fibonacci f2 = new Fibonacci(n - 2);
               return f2.compute() + f1.join();
           }
       }

       public static void main(String[] args) {
           ForkJoinPool pool = new ForkJoinPool();
           Fibonacci task = new Fibonacci(10);
           int result = pool.invoke(task);
           System.out.println("Fibonacci result: " + result);
       }
   }
  

44. Explain the use of `Semaphore` in Java.

A semaphore functions, as a tool for coordinating access to a resource by regulating permits. Its purpose is to manage the access of threads, to a particular resource.
   import java.util.concurrent.Semaphore;

   public class SemaphoreExample {
       private static final Semaphore semaphore = new Semaphore(3);

       public static void main(String[] args) {
           for (int i = 0; i < 10; i++) {
               new Thread(new Worker()).start();
           }
       }

       static class Worker implements Runnable {
           @Override
           public void run() {
               try {
                   semaphore.acquire();
                   System.out.println(Thread.currentThread().getName() + " acquired a permit.");
                   Thread.sleep(2000); // Simulate work
               } catch (InterruptedException e) {
                   e.printStackTrace();
               } finally {
                   semaphore.release();
                   System.out.println(Thread.currentThread().getName() + " released a permit.");
               }
           }
       }
   }

45. What is the difference between `CyclicBarrier` and `CountDownLatch`?

CountDownLatch is employed to have one or more threads pause until a series of tasks are finished, with no option, for reset. On the hand CyclicBarrier is utilized to allow a group of threads to wait for each other at a shared checkpoint and can be reset and used again.
 
   import java.util.concurrent.BrokenBarrierException;
   import java.util.concurrent.CyclicBarrier;

   public class CyclicBarrierExample {
       private static final int PARTIES = 3;
       private static final CyclicBarrier barrier = new CyclicBarrier(PARTIES, () -> System.out.println("All parties arrived. Proceeding..."));

       public static void main(String[] args) {
           for (int i = 0; i < PARTIES; i++) {
               new Thread(new Worker()).start();
           }
       }

       static class Worker implements Runnable {
           @Override
           public void run() {
               try {
                   System.out.println(Thread.currentThread().getName() + " waiting at barrier.");
                   barrier.await();
                   System.out.println(Thread.currentThread().getName() + " proceeded.");
               } catch (InterruptedException | BrokenBarrier

46. What is a ThreadLocal in Java and how is it used?

ThreadLocal offers thread variables. Every thread that interacts with such a variable possesses its initialized version of the variable.
 
public class ThreadLocalExample {
    private static final ThreadLocal threadLocal = ThreadLocal.withInitial(() -> 1);

    public static void main(String[] args) {
        Thread t1 = new Thread(new Worker(), "Thread 1");
        Thread t2 = new Thread(new Worker(), "Thread 2");

        t1.start();
        t2.start();
    }

    static class Worker implements Runnable {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " initial value: " + threadLocal.get());
            threadLocal.set(threadLocal.get() + 1);
            System.out.println(Thread.currentThread().getName() + " updated value: " + threadLocal.get());
        }
    }
}

47. Explain the ReadWriteLock interface and its implementation

ReadWriteLock keeps two locks together one, for reading one for writing. ReentrantReadWriteLock is a version of it that lets multiple readers or one writer work concurrently.
 
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockExample {
    private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private static int value = 0;

    public static void main(String[] args) {
        Thread writer = new Thread(() -> {
            rwLock.writeLock().lock();
            try {
                value++;
                System.out.println("Value incremented to: " + value);
            } finally {
                rwLock.writeLock().unlock();
            }
        });

        Thread reader = new Thread(() -> {
            rwLock.readLock().lock();
            try {
                System.out.println("Read value: " + value);
            } finally {
                rwLock.readLock().unlock();
            }
        });

        writer.start();
        reader.start();
    }
}

48. What is the CompletionService interface in Java?

The CompletionService offers a method to oversee the completion of tasks done asynchronously. It enables you to submit tasks and then obtain their results as they finish.
 
import java.util.concurrent.*;

public class CompletionServiceExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        CompletionService completionService = new ExecutorCompletionService<>(executor);

        for (int i = 0; i < 5; i++) {
            final int taskID = i;
            completionService.submit(() -> {
                Thread.sleep(1000);
                return taskID;
            });
        }

        for (int i = 0; i < 5; i++) {
            try {
                Future future = completionService.take();
                System.out.println("Task completed with result: " + future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        executor.shutdown();
    }
}

49. Explain the use of Exchanger class with an example.

At the exchanger threads can sync up. Swap objects. Each thread brings an object, to the table. Then trades it with the thread.
 
import java.util.concurrent.Exchanger;

public class ExchangerExample {
    private static final Exchanger exchanger = new Exchanger<>();

    public static void main(String[] args) {
        Thread t1 = new Thread(new Task("Hello from T1"));
        Thread t2 = new Thread(new Task("Hello from T2"));

        t1.start();
        t2.start();
    }

    static class Task implements Runnable {
        private final String message;

        Task(String message) {
            this.message = message;
        }

        @Override
        public void run() {
            try {
                String receivedMessage = exchanger.exchange(message);
                System.out.println(Thread.currentThread().getName() + " received: " + receivedMessage);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

50. How does StampedLock work in Java?

StampedLock is a type of lock that functions similarly, to a blend of ReadWriteLock and optimistic locking. It offers three modes; Writing, Reading and Optimistic Reading.
 
import java.util.concurrent.locks.StampedLock;

public class StampedLockExample {
    private final StampedLock stampedLock = new StampedLock();
    private int count = 0;

    public void increment() {
        long stamp = stampedLock.writeLock();
        try {
            count++;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }

    public int read() {
        long stamp = stampedLock.tryOptimisticRead();
        int currentCount = count;
        if (!stampedLock.validate(stamp)) {
            stamp = stampedLock.readLock();
            try {
                currentCount = count;
            } finally {
                stampedLock.unlockRead(stamp);
            }
        }
        return currentCount;
    }

    public static void main(String[] args) {
        StampedLockExample example = new StampedLockExample();
        example.increment();
        System.out.println("Count: " + example.read());
    }
}
Conclusion:
So, here we have covered the most asked Java Multithreading Interview Questions and Answers, from basic to advanced, for all interested candidates. For a complete understanding of Java refer to our Java Full Stack Developer Course.

Download this PDF Now - JAVA Multithreading Interview Questions and Answers PDF By ScholarHat

FAQs

Q1. Is multithreading important in Java for an interview?

Multithreading allows the faster execution of tasks, as threads execute independently

Q2. Can we call run() method of a thread class?

The run() method is available in the thread class constructed using a separate Runnable object. 

Q3. Why multithreading is faster in Java?

Multithreading saves time as you can perform multiple operations together

Q4. How can I prepare for Java Multithreading interview questions?

 Understand core concepts like thread creation, synchronization, locks, and thread communication. Study the Java Concurrency API, including ExecutorService, Future, CountDownLatch, and Semaphore. 

Q5. Where can I find more resources on Java Multithreading?

You can explore Oracle's official Java documentation, our Java Programming Course, GitHub, etc

Q6. What are the advantages of using multithreading in Java?

  • Improved Performance 
  • Enhanced Responsiveness
  • Simplified Modeling 
  •  Resource Sharing 

Q7. What are common Java Multithreading concepts I should know?

  •  Thread Creation 
  •  Synchronization 
  •  Inter-thread Communication 
  •  Thread Lifecycle 
  •  Concurrency Utilities 
  •  Thread Safety 
  •  Volatile Keyword 
Share Article

Live Classes Schedule

Our learn-by-building-project method enables you to build practical/coding experience that sticks. 95% of our learners say they have confidence and remember more when they learn by building real world projects.
.NET Solution Architect Certification TrainingOct 26SAT, SUN
Filling Fast
05:30PM to 07:30PM (IST)
Get Details
.NET Microservices Certification TrainingOct 26SAT, SUN
Filling Fast
05:30PM to 07:30PM (IST)
Get Details
ASP.NET Core Certification TrainingOct 26SAT, SUN
Filling Fast
09:30AM to 11:30AM (IST)
Get Details
Advanced Full-Stack .NET Developer Certification TrainingOct 26SAT, SUN
Filling Fast
09:30AM to 11:30AM (IST)
Get Details
Azure Developer Certification TrainingOct 27SAT, SUN
Filling Fast
08:30PM to 10:30PM (IST)
Get Details
Microsoft Azure Cloud Architect with AINov 10SAT, SUN
Filling Fast
07:00AM to 09:00AM (IST)
Get Details

Can't find convenient schedule? Let us know

About Author
Shailendra Chauhan (Microsoft MVP, Founder & CEO at Scholarhat by DotNetTricks)

Shailendra Chauhan is the Founder and CEO at ScholarHat by DotNetTricks which is a brand when it comes to e-Learning. He provides training and consultation over an array of technologies like Cloud, .NET, Angular, React, Node, Microservices, Containers and Mobile Apps development. He has been awarded Microsoft MVP 9th time in a row (2016-2024). He has changed many lives with his writings and unique training programs. He has a number of most sought-after books to his name which has helped job aspirants in cracking tough interviews with ease.
Accept cookies & close this