multithreading
concurrency
lock mechanisms
thread synchronization
programming concepts

Does lock guarantee acquired in order requested?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

A lock guarantees mutual exclusion, not fairness. It ensures that only one thread enters the protected critical section at a time, but it does not usually guarantee that waiting threads acquire the lock in the same order they requested it. Whether request order is respected depends on the specific lock implementation.

That difference matters because many developers assume "thread-safe" also means "first come, first served." Those are separate properties. A program can be perfectly correct under an unfair lock, and it can also have user-visible latency problems because acquisition order is not predictable.

What a Plain Lock Actually Guarantees

A basic lock normally guarantees:

  • only one thread owns the lock at a time
  • other threads block, spin, or wait until it becomes available
  • the protected region is serialized

What it usually does not promise is FIFO ordering among waiters. If thread A starts waiting before thread B, thread B may still acquire the lock first after release.

That can happen for several reasons:

  • the runtime wakes waiters in a non-FIFO way
  • the operating system scheduler favors a different thread
  • the lock intentionally allows unfair acquisition for throughput reasons

So the right default assumption is "no ordering guarantee unless the API documents one."

Fairness Depends on the Lock Type

Some runtimes expose both fair and unfair lock options. Java is a good example:

java
1import java.util.concurrent.locks.ReentrantLock;
2
3ReentrantLock unfairLock = new ReentrantLock();
4ReentrantLock fairLock = new ReentrantLock(true);

The default constructor creates an unfair lock. Passing true asks for a fairness policy that is closer to acquisition in waiting order.

Even then, fair does not mean perfectly deterministic under every scheduling condition. It means the implementation makes a stronger effort to respect queue order among contenders.

Many mainstream lock types do not provide fairness guarantees at all because unfair locks often perform better under contention.

Why Unfair Locks Often Perform Better

Fairness sounds obviously good until you account for cost. A lock that always wakes the oldest waiter may trigger more context switching and may miss opportunities to let a currently running thread reacquire the lock cheaply.

That is why some runtimes choose unfair behavior by default. They optimize for throughput and average latency rather than strict queue discipline.

For many applications, that is the right tradeoff. If the only requirement is correctness, a fair lock may add overhead without solving a real problem.

Use a Queue When Order Truly Matters

If the application depends on request order, a plain lock is often the wrong abstraction even if a fair mode exists. Order-sensitive work is usually clearer when modeled explicitly through a queue, a worker thread, or a message-passing pipeline.

For example, instead of many threads racing for a lock to process jobs, a queue-based design makes the intended ordering obvious:

python
1from queue import Queue
2from threading import Thread
3
4jobs = Queue()
5
6def worker():
7    while True:
8        job = jobs.get()
9        print(f"processing {job}")
10        jobs.task_done()
11
12Thread(target=worker, daemon=True).start()
13
14for item in ["A", "B", "C"]:
15    jobs.put(item)
16
17jobs.join()

This does not just serialize access. It models ordered processing directly, which is often a better fit than hoping a lock behaves fairly enough.

Common Pitfalls

The biggest mistake is assuming a lock guarantees first-come, first-served acquisition just because multiple threads are waiting.

Another common problem is inferring fairness from light testing. A lock may appear orderly under low contention and behave very differently under real load.

It is also easy to reach for a fair lock when the program really wants an explicit queue or scheduler. Fairness and ordering are related, but they are not interchangeable design concepts.

Finally, lack of fairness can increase starvation risk. A thread may wait much longer than others even though the code remains logically correct.

Summary

  • A normal lock guarantees mutual exclusion, not acquisition order.
  • Fairness exists only when the specific lock implementation documents it.
  • Unfair locks are common because they often deliver better throughput.
  • If strict processing order matters, model that requirement explicitly with queues or schedulers.
  • Do not assume a lock is FIFO unless the API says it is.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.