Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Interview question

What are Race Conditions and Deadlocks? How do you prevent them? Race Conditions और Deadlocks क्या हैं? इन्हें prevent कैसे करते हैं?

Answer

Race conditions occur when multiple threads access shared data simultaneously, causing unpredictable results. Deadlocks occur when threads wait for resources held by each other. Prevention requires careful synchronization and lock ordering.

// Race Condition Example
public class RaceCondition {
    private int counter = 0;
    
    public void increment() {
        counter++;  // NOT atomic
    }
    
    public static void main(String[] args) {
        RaceCondition rc = new RaceCondition();
        
        // 10 threads, each increments 1000 times
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    rc.increment();
                }
            }).start();
        }
        
        // Expected: 10000, Actual: ~5000 (race condition)
        try {
            Thread.sleep(1000);
            System.out.println('Counter: ' + rc.counter);
        } catch (InterruptedException e) {}
    }
}

// Solution: Synchronization
public class FixedCounter {
    private int counter = 0;
    
    public synchronized void increment() {
        counter++;  // Thread-safe
    }
}

// Deadlock Example
public class Deadlock {
    private Object lock1 = new Object();
    private Object lock2 = new Object();
    
    public void method1() {
        synchronized(lock1) {
            System.out.println('Method1: lock1 acquired');
            try { Thread.sleep(100); } catch (InterruptedException e) {}
            
            synchronized(lock2) {  // Waits for lock2
                System.out.println('Method1: lock2 acquired');
            }
        }
    }
    
    public void method2() {
        synchronized(lock2) {  // Acquired first
            System.out.println('Method2: lock2 acquired');
            try { Thread.sleep(100); } catch (InterruptedException e) {}
            
            synchronized(lock1) {  // Waits for lock1 (held by method1)
                System.out.println('Method2: lock1 acquired');
            }
        }
    }
    
    public static void main(String[] args) {
        Deadlock dl = new Deadlock();
        
        new Thread(dl::method1).start();
        new Thread(dl::method2).start();
        
        // Both threads wait for each other - DEADLOCK!
    }
}

// Deadlock Prevention:
// 1. Lock Ordering - always acquire in same order
public class FixedDeadlock {
    private Object lock1 = new Object();
    private Object lock2 = new Object();
    
    public void method1() {
        synchronized(lock1) {  // Always lock1 first
            synchronized(lock2) {
                // Safe
            }
        }
    }
    
    public void method2() {
        synchronized(lock1) {  // Always lock1 first
            synchronized(lock2) {
                // Safe
            }
        }
    }
}

// 2. Timeout - acquire locks with timeout
ReentrantLock lock = new ReentrantLock();
if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try {
        // Do work
    } finally {
        lock.unlock();
    }
}

// 4 conditions for deadlock (prevent any one):
// 1. Mutual Exclusion
// 2. Hold and Wait
// 3. No Preemption
// 4. Circular Wait
Race Conditions:

Problem: Multiple threads same resource
Example: counter++ (3 operations)

Solution:
1. Synchronization
2. Atomic classes
3. Volatile (simple cases)

Deadlock:

Problem: Circular wait for locks
Thread A: has lock1, wants lock2
Thread B: has lock2, wants lock1

Prevention:
1. Lock Ordering - सभी threads same order में
2. Timeout - tryLock(timeout)
3. Avoid nested locks
4. Use high-level frameworks

4 Deadlock Conditions:
1. Mutual Exclusion
2. Hold and Wait
3. No Preemption
4. Circular Wait
(किसी एक को prevent करो)

Was this answer clear?