androidengineers.Book a session
← All interview questions
ThreadIntermediate4 min

What is a Race Condition?

Answer

What is a Race Condition?

A race condition occurs when the behavior of a program depends on the timing or order of uncontrollable events (like thread scheduling). Two or more threads "race" to access shared data, and the final result depends on who wins.

Classic Example

var balance = 100

// Thread 1: Withdraw 80
fun withdraw(amount: Int) {
    if (balance >= amount) {     // Check
        Thread.sleep(10)          // Simulate delay
        balance -= amount         // Update
    }
}

// Thread 2: Withdraw 80
// Both threads check balance=100, both proceed
// Final balance: -60 or 20 (undefined!)

Visual Timeline

Time →
Thread1: if(100>=80)✓ ----delay---- balance=100-80=20
Thread2:    if(100>=80)✓ ----delay---- balance=20-80=-60
                                     ^ Race condition!

Common Race Conditions in Android

1. SharedPreferences

// Both may read old value, one write is lost
prefs.edit().putInt("count", prefs.getInt("count", 0) + 1).apply()

2. Singleton Initialization

object Singleton {
    var instance: Database? = null
    fun get(): Database {
        if (instance == null) {          // Thread 1 & 2 both see null
            instance = Database()        // Two instances created!
        }
        return instance!!
    }
}

3. UI Updates from Background

// May crash if activity is destroyed
thread {
    val data = fetchData()
    textView.text = data  // Not on UI thread + activity may be gone
}

How to Fix

1. Synchronized Access

@Synchronized
fun withdraw(amount: Int) {
    if (balance >= amount) balance -= amount
}

2. Atomic Operations

val balance = AtomicInteger(100)
balance.addAndGet(-80)

3. Thread-Confinement

  • Access data only from one thread
  • Use Handler/Looper or Dispatchers.Main

4. Immutability

  • Use immutable data classes
  • Create new objects instead of modifying

5. Coroutines with Mutex

val mutex = Mutex()
suspend fun withdraw(amount: Int) {
    mutex.withLock {
        if (balance >= amount) balance -= amount
    }
}

Key Takeaway

Race conditions are subtle bugs that don't always crash—they cause intermittent, hard-to-reproduce issues. Always protect shared mutable state!

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