fbpx

Top 100 Java Thread Interview Questions and Answers

Top 100 Java Thread Interview Questions and Answers

Contents show

1. What is a thread in Java?

Answer: A thread in Java represents a separate path of execution within a program. It allows concurrent execution and enables multiple tasks to be performed simultaneously.


2. How can you create a thread in Java?

Answer: You can create a thread by extending the Thread class or by implementing the Runnable interface and passing an instance of it to a Thread object.

// Extending Thread class
class MyThread extends Thread {
    public void run() {
        // Code to be executed in the new thread
    }
}

// Implementing Runnable interface
class MyRunnable implements Runnable {
    public void run() {
        // Code to be executed in the new thread
    }
}

3. What is the difference between Thread and Runnable in Java?

Answer: Thread is a class in Java that directly extends the Thread class, while Runnable is an interface that can be implemented by a class to define the run() method. Implementing Runnable is preferred because it allows the class to extend other classes if needed.


4. How do you start a thread in Java?

Answer: You can start a thread by calling the start() method on the Thread object.

Thread myThread = new MyThread(); // Assuming MyThread extends Thread
myThread.start();

5. Explain the run() method in Java threads.

Answer: The run() method contains the code to be executed in the new thread. It is called when start() is invoked, and it defines the entry point for the thread’s execution.

class MyThread extends Thread {
    public void run() {
        // Code to be executed in the new thread
    }
}

6. Can you explain the difference between start() and run() methods?

Answer: start() is used to begin the execution of a thread, while run() contains the code to be executed in the thread. Calling run() directly won’t create a new thread; it’ll run in the current thread.

Thread myThread = new MyThread();
myThread.start(); // Starts a new thread and executes run()
// vs
myThread.run();   // Executes run() in the current thread

Absolutely, let’s continue with more Java Thread interview questions:


7. What is a thread scheduler?

Answer: The thread scheduler is a part of the JVM that determines which thread should run at any given time. It uses various algorithms to allocate CPU time to threads.


8. Explain the concept of thread priority.

Answer: Thread priority is an integer value associated with a thread that hints to the scheduler about the importance of a thread. It ranges from Thread.MIN_PRIORITY (1) to Thread.MAX_PRIORITY (10), with Thread.NORM_PRIORITY (5) being the default.


9. How can you change the priority of a thread in Java?

Answer: You can use the setPriority(int priority) method to change the priority of a thread.

Thread myThread = new MyThread();
myThread.setPriority(Thread.MAX_PRIORITY); // Set priority to highest

10. What is a daemon thread?

Answer: A daemon thread is a background thread that provides services to non-daemon threads. They do not prevent the JVM from exiting when all non-daemon threads have finished their execution.


11. Explain the difference between wait(), notify(), and notifyAll().

Answer:

  • wait(): Causes the current thread to wait until another thread invokes notify() or notifyAll() on the same object.
  • notify(): Wakes up a single thread that is waiting on this object’s monitor.
  • notifyAll(): Wakes up all threads that are waiting on this object’s monitor.

These methods must be called within a synchronized block.


12. What is thread synchronization in Java?

Answer: Thread synchronization is the mechanism of ensuring that only one thread accesses a shared resource at a time. This is achieved using synchronized blocks or methods.

synchronized (object) {
    // Code to be synchronized
}

13. What is a thread-safe class?

Answer: A thread-safe class is one that can be used by multiple threads simultaneously without causing any issues. It is designed in such a way that its methods can be safely accessed by multiple threads without the need for external synchronization.


14. Explain the concept of a race condition.

Answer: A race condition occurs when two or more threads attempt to modify a shared resource at the same time, leading to unpredictable behavior. This can result in incorrect or inconsistent data.


15. What is the purpose of the volatile keyword in Java?

Answer: The volatile keyword is used to declare a variable as volatile. This ensures that any read or write operation on the variable is directly performed on the main memory, rather than being cached in a thread’s local memory. This helps in preventing visibility issues.

private volatile boolean flag = false;

16. Explain the difference between Thread and Runnable.

Answer:

  • Thread: Represents an independent path of execution in a program. It extends the Thread class and overrides its run() method to define the task.
  • Runnable: Represents a task that can be executed by a thread. It is implemented by providing a run() method, and can be passed to a Thread object for execution.

Using Runnable is generally preferred for better code organization and flexibility.


17. What is the join() method in Java?

Answer: The join() method is used to wait for a thread to finish its execution before the current thread continues. It is particularly useful when you want to ensure that a certain task is completed before moving on.

Thread myThread = new MyThread();
myThread.start();
myThread.join(); // Wait for myThread to finish

18. Explain the concept of a deadlock.

Answer: A deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a lock. This situation typically arises in a multi-threaded environment when resources are not properly synchronized.


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

Answer:

  • wait(): This method is used to make a thread temporarily release its lock and go into a waiting state. It should be called inside a synchronized block or method and can be woken up by another thread using notify() or notifyAll().
  • sleep(): This method causes the current thread to temporarily pause its execution for a specified amount of time. It does not release the lock and is not tied to synchronization.
// Example of wait()
synchronized (object) {
    while (condition) {
        object.wait(); // Releases lock and waits
    }
}

// Example of sleep()
Thread.sleep(1000); // Pauses execution for 1 second

20. What is the purpose of the notify() and notifyAll() methods?

Answer:

  • notify(): This method is used to wake up a single thread that is waiting on the object’s monitor. If there are multiple threads waiting, it is not guaranteed which one will be awakened.
  • notifyAll(): This method wakes up all threads that are waiting on the object’s monitor. It gives all waiting threads a chance to contend for the lock.
// Example of notify()
synchronized (object) {
    object.notify(); // Wakes up a single waiting thread
}

// Example of notifyAll()
synchronized (object) {
    object.notifyAll(); // Wakes up all waiting threads
}

21. What is a thread pool?

Answer: A thread pool is a collection of pre-initialized threads that are ready to perform tasks. It is used to efficiently manage and reuse threads, which can lead to improved performance and resource utilization in multi-threaded applications.

ExecutorService executor = Executors.newFixedThreadPool(5); // Creates a thread pool with 5 threads

22. How do you handle exceptions in a multi-threaded application?

Answer:

  • Use a try-catch block within the run() method of a thread to handle exceptions specific to that thread.
  • Alternatively, you can implement UncaughtExceptionHandler to handle uncaught exceptions globally.
Thread thread = new Thread(() -> {
    try {
        // Code that may throw an exception
    } catch (Exception e) {
        // Handle the exception
    }
});

thread.setUncaughtExceptionHandler((t, e) -> {
    // Global exception handling
});

23. What is the purpose of the join() method in Java?

Answer: The join() method is used to make a thread wait for the completion of another thread. When join() is called on a thread, the calling thread will block until the specified thread completes its execution.

Thread thread = new Thread(() -> {
    // Some time-consuming operation
});

thread.start();
thread.join(); // Waits for 'thread' to complete before continuing

24. Explain the concept of thread synchronization.

Answer: Thread synchronization is the process of controlling the access of multiple threads to shared resources in a concurrent program. It ensures that only one thread can execute a synchronized block of code at a time, preventing concurrent access and potential data corruption.

synchronized (sharedObject) {
    // Code that accesses shared resources
}

25. What is a deadlock in Java?

Answer: A deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a lock. This situation leads to a standstill, and none of the threads can make progress.

// Thread 1
synchronized (resource1) {
    synchronized (resource2) {
        // Code
    }
}

// Thread 2
synchronized (resource2) {
    synchronized (resource1) {
        // Code
    }
}

26. What is a race condition?

Answer: A race condition occurs when two or more threads try to modify shared data at the same time. The outcome of the operation depends on the order of execution, which can lead to unexpected and incorrect results.

int sharedCounter = 0;

// Thread 1
sharedCounter++;

// Thread 2
sharedCounter++;

27. How can you prevent a race condition in Java?

Answer: Race conditions can be prevented using synchronization mechanisms such as locks or synchronized blocks. These techniques ensure that only one thread can access critical sections of code at a time.

private final Object lock = new Object();

synchronized (lock) {
    // Code that modifies shared data
}

28. What is a volatile keyword in Java?

Answer: The volatile keyword is used to indicate that a variable may be modified by multiple threads. It ensures that the variable is always read from and written to main memory, rather than relying on thread-local caches.

private volatile boolean flag = true;

29. What is the difference between wait() and sleep() methods in Java?

Answer:

  • wait() is a method of the Object class that is used for inter-thread communication. It causes the current thread to release the lock and wait until another thread notifies it.
  • sleep() is a method of the Thread class that causes the thread to pause execution for a specified period.
// Using wait()
synchronized (sharedObject) {
    sharedObject.wait(); // Releases lock and waits for notification
}

// Using sleep()
Thread.sleep(1000); // Pauses execution for 1 second

30. What is the purpose of the yield() method in Java?

Answer: The yield() method is a hint to the scheduler that the current thread is willing to yield its current use of the CPU. This allows other threads with the same priority to be scheduled.

Thread.yield(); // Suggests that the thread can be preempted

31. Explain the concept of a daemon thread in Java.

Answer: A daemon thread is a background thread that provides services to non-daemon threads. It runs in the background and does not prevent the JVM from exiting when all non-daemon threads have completed.

Thread daemonThread = new Thread(() -> {
    while (true) {
        // Perform background tasks
    }
});
daemonThread.setDaemon(true); // Set as daemon thread
daemonThread.start();

32. How does the notify() method work in Java?

Answer: The notify() method is used to wake up a single thread that is waiting on the object’s monitor. It is called within a synchronized block or method.

synchronized (sharedObject) {
    sharedObject.notify(); // Notifies a waiting thread
}

33. What is the purpose of the interrupt() method in Java?

Answer: The interrupt() method is used to interrupt a thread, causing it to stop what it is doing and potentially throw an InterruptedException.

Thread thread = new Thread(() -> {
    while (!Thread.currentThread().isInterrupted()) {
        // Do some work
    }
});

thread.start();
// ...
thread.interrupt(); // Signal the thread to interrupt its work

34. How can you create and start a thread in Java?

Answer: You can create a thread by extending the Thread class or implementing the Runnable interface, then calling the start() method.

// Extending Thread class
class MyThread extends Thread {
    public void run() {
        // Thread logic
    }
}

// Implementing Runnable interface
class MyRunnable implements Runnable {
    public void run() {
        // Thread logic
    }
}

// Creating and starting a thread
Thread thread = new Thread(new MyRunnable());
thread.start();

35. What is thread synchronization in Java?

Answer: Thread synchronization is the process of controlling the access to shared resources by multiple threads in a multithreaded environment. It prevents race conditions and ensures that only one thread can access the critical section at a time.


36. Explain the volatile keyword in Java.

Answer: The volatile keyword is used to declare a variable as volatile, which means that its value may be modified by different threads. It ensures that reads and writes to the variable are visible to all threads, preventing thread caching.

volatile int sharedVariable = 0;

37. What is a race condition in multithreading?

Answer: A race condition occurs when two or more threads try to modify shared data at the same time, leading to unpredictable behavior. This can result in incorrect or unexpected outcomes due to the interleaving of instructions.


38. What is a thread pool in Java?

Answer: A thread pool is a collection of pre-initialized threads that are ready to be used for executing tasks. It helps in managing the execution of a large number of tasks efficiently, without the overhead of creating and destroying threads.


39. How does the Executor framework work in Java?

Answer: The Executor framework provides a way to decouple task submission from the mechanics of how each task will be run. It manages a pool of threads, allowing tasks to be submitted for execution.

Executor executor = Executors.newFixedThreadPool(5);
executor.execute(new MyRunnable());

40. Explain the concept of thread-local variables.

Answer: Thread-local variables are variables that have thread scope, meaning each thread has its own independent copy of the variable. Changes made by one thread to its thread-local variable do not affect the value seen by other threads.

ThreadLocal<Integer> threadLocalVariable = ThreadLocal.withInitial(() -> 0);

41. What is the purpose of the join() method in Java?

Answer: The join() method is used to wait for a thread to complete its execution before the current thread continues. It blocks the current thread until the thread it’s waiting for has finished.

Thread thread = new Thread(() -> {
    // Perform some work
});
thread.start();
thread.join(); // Wait for the thread to finish

42. Explain the concept of thread priority in Java.

Answer: Thread priority is a hint to the scheduler about the importance of a thread. Threads with higher priority get preference in execution. However, thread priority behavior may vary across different platforms.


43. What is the purpose of the ReentrantLock class in Java?

Answer: The ReentrantLock class provides a way to create lock objects for synchronized access to critical sections. It allows for finer-grained control over locking and supports features like fairness.

ReentrantLock lock = new ReentrantLock();
lock.lock(); // Acquire the lock
// Critical section
lock.unlock(); // Release the lock

44. Explain the difference between wait() and sleep() in Java.

Answer:

  • wait() is a method defined in the Object class that releases the lock and puts the thread to sleep until it’s notified.
  • sleep() is a method defined in the Thread class that puts the thread to sleep for a specified period of time.
// Example of wait()
synchronized (sharedObject) {
    sharedObject.wait(); // Releases the lock and waits for notification
}

// Example of sleep()
try {
    Thread.sleep(1000); // Sleeps for 1 second
} catch (InterruptedException e) {
    e.printStackTrace();
}

45. What is a daemon thread in Java?

Answer: A daemon thread is a background thread that runs intermittently in the background and provides services to non-daemon threads. It doesn’t prevent the JVM from exiting if all non-daemon threads have completed their execution.


46. Explain the concept of thread deadlock.

Answer: A thread deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a lock. This situation can arise when multiple threads attempt to acquire locks in a different order.


47. What is a thread group in Java?

Answer: A thread group is a way to group threads together for the purpose of managing and controlling them as a single unit. It provides a way to perform operations on multiple threads simultaneously.

ThreadGroup group = new ThreadGroup("MyThreadGroup");
Thread thread1 = new Thread(group, "Thread1");
Thread thread2 = new Thread(group, "Thread2");

48. How can you interrupt a thread in Java?

Answer: You can interrupt a thread by calling the interrupt() method on the thread object. This sets the thread’s interrupt flag, which can be checked using isInterrupted() or handled using InterruptedException.

Thread thread = new Thread(() -> {
    while (!Thread.interrupted()) {
        // Perform some work
    }
});
thread.start();

// Later in code
thread.interrupt(); // Interrupt the thread

49. Explain the concept of thread local memory.

Answer: Thread-local memory refers to memory that is allocated for each thread separately. This memory is not shared among threads, providing each thread with its own isolated storage space.


50. What is the purpose of the yield() method in Java?

Answer: The yield() method is used to hint to the scheduler that the current thread is willing to yield its current use of a processor. This allows the scheduler to decide whether to switch to another thread.

Thread.yield(); // Hint to scheduler to potentially switch threads

51. How does the synchronized keyword work in Java?

Answer: The synchronized keyword is used to create a synchronized block of code or method. It ensures that only one thread can execute the synchronized code block at a time, preventing concurrent access by multiple threads.

// Synchronized block
synchronized (sharedObject) {
    // Code to be synchronized
}

// Synchronized method
public synchronized void synchronizedMethod() {
    // Code to be synchronized
}

52. What is a race condition in the context of multithreading?

Answer: A race condition occurs when two or more threads access shared data or resources in an unpredictable order, potentially leading to incorrect or unexpected behavior. It happens when the outcome of the program depends on the order of execution of concurrent threads.


53. What is the purpose of the volatile keyword in Java?

Answer: The volatile keyword is used to declare a variable as volatile, which means it can be accessed by multiple threads. It ensures that any read or write operation on the variable is directly performed on the main memory, preventing thread-local caching.

private volatile int counter = 0;

54. Explain the concept of thread priority.

Answer: Thread priority is a way to influence the scheduling of threads. Threads with higher priority values are scheduled to run before threads with lower priority values. However, it’s important to note that thread priority is just a hint and the actual behavior may vary between different JVM implementations.


55. What is a thread pool in Java?

Answer: A thread pool is a managed collection of threads that are created and managed by an executor. It allows for the efficient reuse of threads, reducing the overhead of creating new threads for every task.

ExecutorService executor = Executors.newFixedThreadPool(5);

56. How does the join() method work in Java?

Answer: The join() method is used to make one thread wait for the completion of another thread. When thread.join() is called, the current thread will wait until thread has completed its execution.

Thread thread = new Thread(() -> {
    // Perform some work
});
thread.start();
thread.join(); // Wait for thread to finish

57. What is a deadlock in multithreading?

Answer: A deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a lock. This situation can happen if multiple threads acquire locks in different orders.


58. Explain the concept of thread safety.

Answer: Thread safety refers to the property of a program or a portion of code that ensures it functions correctly during simultaneous execution by multiple threads. This often involves using synchronization to protect shared data from concurrent access.


59. How can you prevent a deadlock in Java?

Answer: To prevent deadlocks, you can follow best practices such as acquiring locks in a consistent order, using timeouts, and avoiding unnecessary nested locks. Additionally, you can use tools like thread profiling to detect and resolve potential deadlocks.


60. What is the difference between notify() and notifyAll()?

Answer: Both notify() and notifyAll() are methods in the Object class used for inter-thread communication. notify() wakes up one randomly selected waiting thread, while notifyAll() wakes up all waiting threads.

// Using notify()
synchronized (lock) {
    lock.notify(); // Wakes up one waiting thread
}

// Using notifyAll()
synchronized (lock) {
    lock.notifyAll(); // Wakes up all waiting threads
}

61. What is the purpose of the ThreadLocal class in Java?

Answer: The ThreadLocal class provides thread-local variables. Each thread accessing a ThreadLocal variable has its own independent copy. This is useful when you want to associate a unique piece of data with each thread.

private static ThreadLocal<Integer> threadLocalValue = ThreadLocal.withInitial(() -> 0);

// Access thread-local variable
int value = threadLocalValue.get();

62. Explain the difference between preemptive and cooperative multitasking.

Answer:

  • Preemptive multitasking: In preemptive multitasking, the operating system can interrupt a running thread to start or resume another thread. The scheduler decides when to switch between threads.
  • Cooperative multitasking: In cooperative multitasking, a running thread decides when to give up control and allow another thread to run. This requires threads to voluntarily yield control.

63. What is the purpose of the volatile keyword in Java?

Answer: The volatile keyword is used to declare a variable as volatile, which ensures that reads and writes to the variable are always done directly from and to main memory, bypassing thread-local caches. This is crucial for variables accessed by multiple threads.

private volatile boolean flag = true;

64. Explain the difference between Runnable and Thread in Java.

Answer:

  • Runnable: It is an interface that defines a single method run(). You can implement this interface to define the code that a thread will execute.
  • Thread: It is a class in Java that extends the Thread class itself. When you create an instance of Thread, you can either provide a Runnable or override the run() method directly.
// Using Runnable
Runnable myRunnable = () -> { /* Code to be executed */ };
Thread thread1 = new Thread(myRunnable);

// Extending Thread
Thread thread2 = new Thread() {
    public void run() { /* Code to be executed */ }
};

65. How does a CountDownLatch work in Java?

Answer: CountDownLatch is a synchronization aid that allows one or more threads to wait until a set of operations in other threads completes. It initializes with a count, and threads can call await() until the count reaches zero.

CountDownLatch latch = new CountDownLatch(3);

// In other threads
latch.countDown(); // Decrement the count

// In another thread waiting for completion
latch.await(); // Wait until count becomes zero

66. Explain the purpose of the join() method in Java.

Answer: The join() method is used to wait for a thread to finish its execution. When you call join() on a thread, the current thread will pause and wait for the target thread to complete before it continues execution.

Thread thread = new Thread(() -> {
    // Code to be executed
});

thread.start();
thread.join(); // Wait for thread to finish

67. What is a thread pool in Java?

Answer: A thread pool is a collection of reusable threads that can be used to execute tasks concurrently. It helps in managing the execution of a large number of tasks without creating a new thread for each task, which can be costly.

ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(() -> { /* Task to be executed */ });

68. What is the purpose of the synchronized keyword in Java?

Answer: The synchronized keyword is used to create a synchronized block or method, which allows only one thread to execute that block of code at a time. It ensures that the critical section is accessed by only one thread, preventing race conditions.

public synchronized void synchronizedMethod() {
    // Code to be executed
}

69. Explain the concept of deadlock in multithreading.

Answer: Deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a lock. This can happen if locks are acquired in a different order in different threads.

// Thread 1
synchronized (resource1) {
    synchronized (resource2) {
        // Code to be executed
    }
}

// Thread 2
synchronized (resource2) {
    synchronized (resource1) {
        // Code to be executed
    }
}

70. What is the purpose of the ReentrantLock class in Java?

Answer: ReentrantLock is an alternative to the synchronized keyword for controlling access to a shared resource by multiple threads. It provides more flexibility and features, such as fairness, which allows the longest-waiting thread to acquire the lock.

ReentrantLock lock = new ReentrantLock();

lock.lock(); // Acquire lock
try {
    // Code to be executed
} finally {
    lock.unlock(); // Release lock in finally block
}

71. Explain the difference between wait() and sleep() in Java.

Answer:

  • wait(): It is a method of the Object class and is used for inter-thread communication. It releases the lock and puts the thread in a waiting state until it’s notified.
  • sleep(): It’s a static method of the Thread class and is used to pause the execution of a thread for a specified amount of time.
// Using wait()
synchronized (obj) {
    obj.wait(); // Releases lock and waits
}

// Using sleep()
Thread.sleep(1000); // Pauses the thread for 1 second

72. What is the purpose of the volatile keyword in Java?

Answer: The volatile keyword is used to declare a variable as volatile, which means its value may be modified by different threads. It ensures that any read of the variable will see the most recently written value.

volatile boolean flag = true;

73. Explain the concept of thread pooling.

Answer: Thread pooling is a technique where a fixed number of threads are created and kept in a pool. When a task arrives, a thread from the pool is assigned to handle it. This reduces the overhead of creating new threads for every task.

ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(new MyTask());

74. What is a CountDownLatch in Java?

Answer: CountDownLatch is a synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. It’s initialized with a count and decrements it each time a task completes.

CountDownLatch latch = new CountDownLatch(3);

75. Explain the purpose of the join() method in Java.

Answer: The join() method is used to wait for a thread to die. It pauses the current thread’s execution until the target thread completes. This is useful when you want to ensure that a certain thread has finished before continuing.

Thread thread = new Thread(new MyRunnable());
thread.start();
thread.join(); // Wait for thread to finish

76. What is the difference between a thread and a process?

Answer:

  • A process is an instance of a program in execution, while a thread is a unit of execution within a process.
  • Processes have their own memory space, while threads share the same memory space.
  • Processes are heavyweight, requiring separate memory and resources, while threads are lighter and share resources.
// Creating a process
ProcessBuilder processBuilder = new ProcessBuilder("myProgram.exe");
Process process = processBuilder.start();

// Creating a thread
Thread thread = new Thread(new MyRunnable());
thread.start();

77. What is the purpose of the ThreadLocal class in Java?

Answer: The ThreadLocal class provides thread-local variables. Each thread accessing a ThreadLocal variable has its own independently initialized copy, which is not shared with other threads.

ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);

78. What is deadlock in a multi-threaded environment?

Answer: Deadlock is a situation where two or more threads are unable to proceed because each is waiting for the other to release a lock. This results in a standstill, and the program can’t progress.

// Example of deadlock
Thread t1 = new Thread(() -> {
    synchronized (resource1) {
        synchronized (resource2) {
            // Code
        }
    }
});

Thread t2 = new Thread(() -> {
    synchronized (resource2) {
        synchronized (resource1) {
            // Code
        }
    }
});

79. What is the purpose of the yield() method in Java?

Answer: The yield() method is used to give a hint to the scheduler that the current thread is willing to yield its current use of a processor. It allows other threads of the same priority to be scheduled.

Thread.yield();

80. Explain the concept of a daemon thread in Java.

Answer: A daemon thread is a low-priority thread that runs in the background and provides services to other threads or objects. It doesn’t prevent the program from terminating if all non-daemon threads have finished.

Thread daemonThread = new Thread(new DaemonRunnable());
daemonThread.setDaemon(true);
daemonThread.start();

81. What is the purpose of the interrupt() method in Java?

Answer: The interrupt() method is used to interrupt a thread. It doesn’t stop the thread immediately, but sets its interrupt flag, allowing the thread to exit gracefully at an appropriate point.

Thread thread = new Thread(new MyRunnable());
thread.start();
// ...
thread.interrupt(); // Request for interruption

82. Explain the difference between wait(), notify(), and notifyAll() in Java.

Answer:

  • wait(): It causes the current thread to wait until another thread invokes the notify() or notifyAll() method for the same object.
  • notify(): It wakes up a single thread that is waiting on this object’s monitor.
  • notifyAll(): It wakes up all threads that are waiting on this object’s monitor.
// Example of wait() and notify()
synchronized (lock) {
    while (!condition) {
        lock.wait(); // Release lock and wait
    }
    lock.notify(); // Notify waiting thread
}

83. How can you prevent a thread from being interrupted?

Answer: You can prevent a thread from being interrupted by catching the InterruptedException and ignoring it, or by using Thread.interrupted() to clear the interrupt status.

try {
    // Code that may throw InterruptedException
} catch (InterruptedException e) {
    // Ignore the interruption
}

84. How does the join() method work in Java?

Answer: The join() method is used to wait for a thread to die. It causes the currently executing thread to pause until the thread on which it is called terminates.

Thread t1 = new Thread(() -> {
    // Code
});

t1.start();
t1.join(); // Wait for t1 to finish

85. What is a thread pool in Java?

Answer: A thread pool is a collection of pre-initialized threads that are ready to be used. It manages and reuses threads to execute tasks, improving performance by avoiding the overhead of creating new threads.

ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(new Task());

86. Explain the significance of the volatile keyword in Java.

Answer: The volatile keyword is used to indicate that a variable’s value may be modified by multiple threads. It ensures that any read of the variable is always up-to-date with the latest value.

private volatile boolean flag = false;

87. What is a race condition in the context of multithreading?

Answer: A race condition occurs when two or more threads attempt to update shared data at the same time, leading to unpredictable and erroneous behavior.

public void incrementCounter() {
    counter++; // Race condition can occur here
}

88. Explain the concept of thread-local variables.

Answer: Thread-local variables are variables that are specific to each thread. Each thread has its own copy of a thread-local variable, and changes made by one thread do not affect the value seen by other threads.

private static ThreadLocal<String> threadLocal = new ThreadLocal<>();

89. How can you handle exceptions in a multithreaded application?

Answer: Exceptions in a multithreaded application can be handled by using try-catch blocks within the run() method of the Runnable interface. Additionally, uncaught exceptions can be caught by implementing Thread.UncaughtExceptionHandler.

Thread thread = new Thread(() -> {
    try {
        // Code that may throw an exception
    } catch (Exception e) {
        // Handle the exception
    }
});

90. What is a ReentrantLock in Java?

Answer: A ReentrantLock is a synchronization primitive similar to synchronized blocks. It allows threads to lock critical sections of code and provides more flexibility, such as timeouts and condition variables.

ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
    // Critical section
} finally {
    lock.unlock();
}

91. What is a daemon thread in Java?

Answer: A daemon thread is a thread that runs in the background, providing services to non-daemon threads. When all non-daemon threads finish execution, the JVM terminates any remaining daemon threads.

Thread daemonThread = new Thread(() -> {
    while (true) {
        // Perform background tasks
    }
});

daemonThread.setDaemon(true);
daemonThread.start();

92. Explain the concept of a thread-safe class in Java.

Answer: A thread-safe class is one that can safely be used by multiple threads without causing issues like race conditions or incorrect results. This is typically achieved by using synchronization mechanisms like locks.

public class ThreadSafeCounter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }
}

93. How can you prevent deadlock in a multithreaded application?

Answer: Deadlock can be prevented by ensuring that threads always acquire locks in a consistent order. Additionally, timeouts can be used when acquiring locks to avoid situations where a lock is held indefinitely.

if (lock1.tryLock(100, TimeUnit.MILLISECONDS)) {
    if (lock2.tryLock(100, TimeUnit.MILLISECONDS)) {
        // Code
    }
    lock2.unlock();
}
lock1.unlock();

94. What is the purpose of the yield() method in Java?

Answer: The yield() method is used to hint to the scheduler that the current thread is willing to give up its current time slice and allow other threads to run. It does not guarantee that the scheduler will honor the request.

public void run() {
    // Code
    Thread.yield(); // Hint to the scheduler
    // Code
}

95. Explain the difference between notify() and notifyAll() methods.

Answer: Both methods are used to signal threads that a condition has changed. notify() wakes up a single waiting thread, while notifyAll() wakes up all waiting threads. It’s generally safer to use notifyAll() to avoid potential missed signals.

synchronized (lock) {
    lock.notify(); // or lock.notifyAll()
}

96. What is a thread dump in Java and how can it be generated?

Answer: A thread dump is a snapshot of the state of all threads in a Java application at a specific point in time. It provides information about thread names, states, and stack traces.

To generate a thread dump:

  • On Unix-like systems: Send the QUIT signal to the Java process (kill -QUIT <pid>).
  • On Windows: Use the Task Manager or a tool like jVisualVM.

97. Explain the purpose of the ThreadLocalRandom class in Java.

Answer: ThreadLocalRandom provides a random number generator that is local to each thread. It’s typically faster and has less contention than using java.util.Random in a multithreaded context.

int randomNum = ThreadLocalRandom.current().nextInt(1, 101);

98. What is the purpose of the volatile keyword in Java?

Answer: The volatile keyword is used to indicate that a variable may be modified by multiple threads and should not be cached in thread-local memory. It ensures that changes made by one thread are visible to other threads.

public class SharedResource {
    private volatile int count = 0;
}

99. Can you explain the difference between sleep() and wait() methods in Java?

Answer:

  • sleep() is a static method in the Thread class that pauses the current thread for a specified period of time. It does not release any locks.
  • wait() is a method in the Object class that causes the current thread to wait until another thread invokes notify() or notifyAll() on the same object. It releases the lock on the object.
synchronized (lock) {
    lock.wait(); // Waits for a notification
    // Code after notification
}

100. How can deadlock situations be detected and resolved in Java?

Answer: Deadlock detection can be done using tools like jVisualVM or thread dump analysis. To resolve deadlocks, techniques like:

  • Avoiding nested locks.
  • Using tryLock() with timeouts.
  • Ensuring locks are acquired in a consistent order.
// Example of using tryLock() with timeouts
if (lock1.tryLock(100, TimeUnit.MILLISECONDS)) {
    if (lock2.tryLock(100, TimeUnit.MILLISECONDS)) {
        // Code
    }
    lock2.unlock();
}
lock1.unlock();