WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Java Concurrency · Basic · question 14 of 100

How can you prevent deadlock in a multi-threaded application?

📕 Buy this interview preparation book: 100 Java Concurrency questions & answers — PDF + EPUB for $5

Deadlocks can occur in a multi-threaded application when multiple threads acquire locks on resources in different orders, leading to a situation where each thread is waiting for a lock that is held by another thread. Here are some strategies for preventing deadlocks:

Use a consistent locking order: To prevent deadlocks, it is important to use a consistent locking order for shared resources. This means that threads should always acquire locks on resources in the same order to avoid potential conflicts.

Release locks as soon as possible: Holding locks for long periods of time can increase the likelihood of deadlocks occurring. To prevent deadlocks, it is important to release locks as soon as they are no longer needed.

Use higher-level synchronization constructs: Higher-level synchronization constructs, such as semaphores or monitors, can provide more flexible ways to manage shared resources and prevent deadlocks.

Avoid nested locks: Nested locks, where a thread acquires multiple locks at once, can increase the likelihood of deadlocks occurring. To prevent deadlocks, it is important to avoid nested locks whenever possible.

Here’s an example of using a consistent locking order to prevent deadlocks in Java:

public class DeadlockPreventionExample {
    private static Object lock1 = new Object();
    private static Object lock2 = new Object();
    
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread 1 acquired lock1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("Thread 1 acquired lock2");
                }
            }
        });
    
        Thread thread2 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread 2 acquired lock1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("Thread 2 acquired lock2");
                }
            }
        });
    
        thread1.start();
        thread2.start();
    }
}

In this example, we define two threads that acquire locks in a consistent order to prevent deadlocks. Both threads first acquire lock1 before acquiring lock2, ensuring that there is no conflict over the shared resources.

Overall, preventing deadlocks in a multi-threaded application requires careful planning and design to ensure that threads are acquiring locks in a consistent order, releasing locks as soon as possible, and using higher-level synchronization constructs where appropriate. By following these strategies, developers can minimize the risk of deadlocks occurring and ensure that their multi-threaded applications run smoothly and efficiently.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Java Concurrency interview — then scores it.
📞 Practice Java Concurrency — free 15 min
📕 Buy this interview preparation book: 100 Java Concurrency questions & answers — PDF + EPUB for $5

All 100 Java Concurrency questions · All topics