androidengineers.Book a session
โ† All interview questions
ThreadAdvanced5 min

What is a Deadlock and how to avoid it?

Answer

What is a Deadlock?

A deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a lock.

Classic Example

val lockA = Any()
val lockB = Any()

// Thread 1
synchronized(lockA) {
    Thread.sleep(100)
    synchronized(lockB) {  // Waits for Thread 2 to release lockB
        println("Thread 1")
    }
}

// Thread 2
synchronized(lockB) {
    Thread.sleep(100)
    synchronized(lockA) {  // Waits for Thread 1 to release lockA
        println("Thread 2")
    }
}

// DEADLOCK! Both threads wait forever

Four Conditions for Deadlock

All four must be present:

  1. Mutual Exclusion - Resources can't be shared
  2. Hold and Wait - Thread holds one resource, waits for another
  3. No Preemption - Resources can't be forcibly taken
  4. Circular Wait - Thread 1 waits for Thread 2, Thread 2 waits for Thread 1

How to Avoid Deadlocks

1. Lock Ordering

Always acquire locks in the same order:

// Always lock A before B
synchronized(lockA) {
    synchronized(lockB) { ... }
}

2. Lock Timeout (tryLock)

val lock = ReentrantLock()
if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try { /* work */ } finally { lock.unlock() }
} else {
    // Handle timeout
}

3. Use Higher-Level Concurrency

// Coroutines handle this better
val mutex = Mutex()
mutex.withLock { /* safe */ }

4. Avoid Nested Locks

Design to minimize the need for multiple locks.

5. Use Thread-Safe Data Structures

ConcurrentHashMap instead of synchronized HashMap.

Detecting Deadlocks

  • Thread Dump: kill -3 <pid> or jstack
  • ANR Traces: Check /data/anr/traces.txt
  • Android Studio Profiler: CPU thread view
  • StrictMode: Can detect some issues

Mark this when you can explain the answer in your own words.

Share & Help Others

Help fellow developers prepare for interviews

Sharing helps the Android community grow ๐Ÿ’š

Keep practising