Thread Safety

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • Thread Safety means that a class or method behaves correctly when accessed by multiple threads simultaneously, without requiring the calling code to add additional synchronization.
  • To achieve thread safety, you must protect shared, mutable state.

Concept

If a class is “Not Thread-Safe” (like ArrayList or HashMap), it means if 5 threads try to add data to it at the same time, the internal data structure might corrupt, throw exceptions, or lose data.

If a class is “Thread-Safe” (like Vector or ConcurrentHashMap), it handles internal synchronization itself. Developers can safely share one instance of this class among 100 threads without worrying about race conditions.

How to achieve Thread Safety:

  1. Statelessness: If a method doesn’t use instance variables (only local variables on the stack), it is inherently thread-safe.
  2. Immutability: If an object cannot be modified after creation, it is thread-safe.
  3. Synchronization: Using synchronized blocks or Lock objects to protect mutable data.
  4. ThreadLocal: Giving each thread its own isolated copy of a variable.
  5. Atomic Classes: Using AtomicInteger instead of int.

Examples

// NOT THREAD SAFE
class Counter {
    private int count = 0; // Shared, mutable state
    
    public void increment() {
        count++; // Race condition waiting to happen
    }
}

// THREAD SAFE (via Synchronization)
class SafeCounter {
    private int count = 0;
    
    public synchronized void increment() {
        count++; // Protected
    }
}

// THREAD SAFE (via Statelessness)
class MathUtils {
    // No instance variables. Local variables live on the Thread Stack.
    // 100% inherently thread safe.
    public int add(int a, int b) {
        int result = a + b; 
        return result;
    }
}

Interview Questions

Q: Are local variables thread-safe?
A: Yes, absolutely. Local variables (variables declared inside a method) are stored on the Thread Stack. Every single thread has its own private, isolated stack memory. Therefore, it is physically impossible for Thread A to access a local variable inside Thread B’s stack. However, be careful if the local variable is a reference to a mutable object on the shared Heap!

Q: What is ThreadLocal?
A: ThreadLocal is a special class that allows you to create variables that can only be read and written by the same thread. For example, SimpleDateFormat is notoriously not thread-safe. Instead of using heavy synchronized blocks, you can put it inside a ThreadLocal<SimpleDateFormat>. When a thread calls .get(), Java ensures it receives its own private, isolated instance of the formatter.