What is lock contention in a multithreaded Java program, and why does it hurt performance?
answer
- One holder, many waiters
- Wait time + context-switch overhead
- Serialization → Amdahl's law caps speedup
- Contended counter can be slower than single-threaded
- Fix: shorter critical section, finer locks, or no lock
basics
~20 sLock contention happens when several threads try to acquire the same lock at the same time. Only one can hold it, so the others wait. The more threads compete, the more time is spent waiting instead of doing real work, so the program slows down.
solid answer
~40 sLock contention is when multiple threads compete for the same lock simultaneously. A lock is mutually exclusive, so only one thread holds it at a time; the rest block until it is released. Contention hurts performance two ways: directly, through the time threads spend waiting (and the OS context-switch / thread-park overhead to put waiters to sleep and wake them), and indirectly, by serializing work that could otherwise run in parallel, capping your speedup (Amdahl's law). Under heavy contention a synchronized section can even run slower than single-threaded code because of the coordination overhead. The fixes are to hold locks for less time (narrow the critical section), lock at a finer granularity so threads contend on different locks, or avoid locking via immutable data, thread-confinement, or lock-free atomics.
go deeper
Can define lock contention as threads waiting for the same lock and say it slows the program because only one thread proceeds at a time.
Adds the mechanism — blocking, parking, context-switch overhead — and knows uncontended locks are cheap while contended ones aren't.
Frames contention as serialization governed by Amdahl's law, can reason about when it dominates, and names concrete reduction strategies (narrower sections, finer locks, lock-free).
Reasons about system-level impact (scalability ceilings, tail latency, throughput collapse under load), measurement via JFR/profilers, and chooses between lock-splitting, lock-free, and architectural changes (sharding, immutability) with trade-offs.
## First principles When two or more threads share mutable data, you need **mutual exclusion** so they don't corrupt it by interleaving reads and writes. In Java the basic tool is a **lock** (the `synchronized` keyword, or a `java.util.concurrent.locks.Lock` such as `ReentrantLock`). A lock has a simple rule: **at most one thread can hold it at a time.** The region of code that runs while holding the lock is the **critical section**. ## What 'contention' means **Contention** = competition. **Lock contention** is the situation where, at the moment a thread wants to *acquire* a lock, another thread already *holds* it (or several threads are queued for it). The wanting threads cannot proceed; they **block** (are suspended) until the lock is free. - **Uncontended lock:** when a thread asks for the lock, it's free, so it takes it immediately and moves on. This is cheap — on the JVM an uncontended `synchronized` is often optimized to a handful of instructions (biased/thin locking, lock elision). - **Contended lock:** the thread must wait. The JVM may first **spin** (busy-loop briefly, hoping the holder releases soon), and if that fails, **park** the thread — hand it to the OS, which removes it from the CPU and schedules another thread. Waking it later is a **context switch**. ## Why it hurts performance 1. **Waiting time.** A blocked thread does no useful work while it waits. 2. **Coordination overhead.** Parking and unparking threads costs CPU and triggers OS context switches, cache disturbance, and scheduler work. Under heavy contention this overhead can dominate. 3. **Serialization (the deep reason).** A lock forces the protected work to run **one thread at a time**. So even with 16 cores, the locked portion runs sequentially. **Amdahl's law** says your maximum speedup is limited by the fraction of work that must be serial: if 20% of the work is inside one global lock, you can never go faster than 5x no matter how many cores you add. Contention is how that serial fraction shows up at runtime. A classic, counter-intuitive result: a heavily contended `synchronized` counter can be *slower* with many threads than with one, because the threads spend almost all their time fighting over the lock and being context-switched, not incrementing. ## How you reduce it (preview) - **Narrow the critical section:** do less work while holding the lock — move I/O, allocation, and pure computation outside it. - **Finer granularity:** split one big lock into several, so threads that touch *different* data contend on *different* locks (e.g. lock striping in `ConcurrentHashMap`). - **Avoid locking entirely:** immutable objects (no writes to coordinate), thread-confined data (each thread owns its own copy), read-mostly data behind `ReadWriteLock`/`StampedLock`, or lock-free atomics (`AtomicLong`, `LongAdder`). ## How you *see* it Thread dumps showing many threads `BLOCKED` on the same monitor, profilers/JFR 'monitor blocked' or 'lock contention' events, and `LongAdder` outperforming `AtomicLong` under load are all signals of contention.
- Why can a heavily contended synchronized counter be slower than a single-threaded one?Because the threads spend most of their time acquiring/releasing the lock and being parked/unparked (context switches) rather than incrementing; the actual increment work is serialized anyway, so you pay coordination overhead on top of sequential execution.
- Is an uncontended lock expensive?No. The JVM optimizes uncontended locking heavily (biased/thin locks, and even lock elision via escape analysis), so it costs very little. The cost appears mainly when threads actually compete.
saying these in an interview costs you the question
- Claiming any synchronized code is automatically slow — uncontended locks are cheap
- Confusing contention (waiting for a lock) with deadlock (mutual permanent wait)
- Thinking more threads always means more throughput regardless of locking
- Saying contention causes incorrect results — it causes slowness, not data corruption