Learnitweb

Fair vs Non-Fair Locks in Java

1. What is a Lock?

A lock is a synchronization mechanism that allows only one thread at a time to access a critical section (shared resource or code block).

Java provides various lock implementations in the java.util.concurrent.locks package, especially the ReentrantLock class, which supports fair and non-fair locking policies.

2. Fair Lock

2.1 What is it?

A fair lock ensures first-come, first-served access to threads. That means:

  • The thread that has been waiting the longest gets the lock first.
  • It respects the order of arrival, preventing starvation.

2.2 Behavior:

  • Threads are queued in an internal FIFO queue.
  • When the lock becomes available, the next thread in line gets it.
  • Ensures predictable and equal access for all threads.

2.3 How to create a fair lock:

ReentrantLock fairLock = new ReentrantLock(true);

The true parameter specifies fairness.

2.4 Example:

ReentrantLock lock = new ReentrantLock(true); // fair

public void doWork() {
    lock.lock();
    try {
        // critical section
    } finally {
        lock.unlock();
    }
}

2.5 Pros of Fair Lock:

  • Avoids thread starvation.
  • Ensures orderly and predictable lock access.
  • Useful in real-time or high-integrity systems where fairness is important.

2.6 Cons of Fair Lock:

  • Slightly slower performance due to queue management overhead.
  • More context switching, as it might pass over a ready thread in favor of one that’s been waiting longer.

3. Non-Fair Lock

3.1 What is it?

A non-fair lock allows any waiting thread to acquire the lock — regardless of arrival order. This means:

  • The currently waiting threads may be bypassed.
  • The thread trying to acquire the lock can sometimes “jump the queue”.

3.2 Behavior:

  • No guaranteed order.
  • Can lead to thread starvation, especially for low-priority threads.
  • Often faster in high-concurrency environments.

3.3 Default in ReentrantLock:

ReentrantLock nonFairLock = new ReentrantLock(); // default is false (non-fair)

3.4 Example:

ReentrantLock lock = new ReentrantLock(false); // or omit the parameter

public void doWork() {
    lock.lock();
    try {
        // critical section
    } finally {
        lock.unlock();
    }
}

4. Pros of Non-Fair Lock:

  • Higher throughput, because ready threads don’t have to wait in line.
  • Threads can acquire locks quickly, even if they arrived later.
  • Less overhead, better for performance-critical applications.

5. Cons of Non-Fair Lock:

  • Can result in thread starvation.
  • No predictability — lower priority threads may never get a chance.
  • Not suitable where fairness or order matters.

6. Best Practices

  • Use non-fair locks in high-performance scenarios where fairness is not a concern.
  • Use fair locks in:
    • Real-time systems
    • Queued task processing
    • Financial systems (e.g., banking transactions)
    • Shared system resources where starvation must be avoided
  • Avoid mixing fair and non-fair locks in the same application — it can lead to unpredictable behavior.