A deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a lock.
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
All four must be present:
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.
Mark this when you can explain the answer in your own words.
Help fellow developers prepare for interviews
Sharing helps the Android community grow ๐