Skip to content

Advanced Locking & Patterns in Java

1. Lock Fairness

Locks can be fair or non-fair:

  • Fair locks: Threads acquire the lock in the order they requested it (FIFO).
  • Non-fair locks: Threads may “cut in line,” giving better throughput but risking starvation.

In Java:

java
ReentrantLock fairLock = new ReentrantLock(true);  // fair
ReentrantLock unfairLock = new ReentrantLock(false); // default non-fair

Trade-offs:

  • Fair locks improve predictability but reduce throughput.
  • Non-fair locks improve performance but may starve low-priority threads.

2. Deadlock: Causes & Prevention

A deadlock occurs when threads wait on each other indefinitely.
Conditions for deadlock:

  1. Mutual exclusion — only one thread at a time can access a resource.
  2. Hold and wait — a thread holds a resource and waits for another.
  3. No preemption — resources cannot be forcibly taken.
  4. Circular wait — a cycle of threads waiting for each other’s locks.

Example: Classic Deadlock

java
class DeadlockExample {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    public void method1() {
        synchronized (lock1) {
            synchronized (lock2) {
                System.out.println("method1");
            }
        }
    }

    public void method2() {
        synchronized (lock2) {
            synchronized (lock1) {
                System.out.println("method2");
            }
        }
    }
}

Prevention Strategies

  • Lock ordering: Always acquire locks in a consistent global order.
  • tryLock() with timeout: Use ReentrantLock.tryLock(timeout) to avoid waiting indefinitely.
  • Detect and recover: Monitor thread states and restart stuck processes (more common in databases).

3. Starvation and Livelock

  • Starvation: A thread never acquires resources because others always get ahead.

    • Cause: unfair scheduling or lock bias.
    • Fix: use fair locks or better scheduling policies.
  • Livelock: Threads keep responding to each other but make no progress.

    • Example: Two threads backing off and retrying forever.
    • Fix: randomized backoff, or adding priority rules.

4. Lock Striping for Performance

Lock striping divides a resource into smaller segments, each protected by its own lock. This increases concurrency.

Example

java
class LockStripedCache {
    private final Object[] locks;
    private final Map<Integer, String> map;

    public LockStripedCache(int stripes) {
        locks = new Object[stripes];
        for (int i = 0; i < stripes; i++) locks[i] = new Object();
        map = new HashMap<>();
    }

    public void put(int key, String value) {
        int lockIndex = key % locks.length;
        synchronized (locks[lockIndex]) {
            map.put(key, value);
        }
    }

    public String get(int key) {
        int lockIndex = key % locks.length;
        synchronized (locks[lockIndex]) {
            return map.get(key);
        }
    }
}

This reduces contention compared to one global lock.


5. Best Practices

  • Always release locks in a finally block:
java
lock.lock();
try {
    // critical section
} finally {
    lock.unlock();
}
  • Avoid nested locks — they increase risk of deadlocks.
  • Keep critical sections short and focused.
  • Use higher-level concurrency utilities (BlockingQueue, ConcurrentHashMap) instead of manual locking when possible.
  • Prefer immutable objects to reduce need for synchronization.

6. Interview Focus

Q: How do you avoid deadlocks in Java?

  • Acquire locks in a consistent global order.
  • Use tryLock() with timeout instead of blocking forever.
  • Keep lock scope small.
  • Use higher-level concurrency utilities when possible.

Q: Difference between starvation and livelock?

  • Starvation: A thread never progresses because others dominate resources.
  • Livelock: Threads actively change state in response to others but still make no progress.

Conclusion

Advanced locking introduces nuances like fairness, starvation, livelock, and patterns like lock striping. Understanding these helps you write robust concurrent code and answer interview questions confidently.