Skip to content

Java Locks โ€‹

๐Ÿงฉ 1. What Is a "Lock"? โ€‹

A lock is a mechanism in multithreaded concurrent programming used to control access to shared resources.

Core goal: Prevent multiple threads from modifying the same data simultaneously, which could cause data inconsistency (thread-safety issues).


๐ŸŽฏ Real-world Analogy โ€‹

Imagine you and others share a folder (a shared resource):

  • Without a lock: you both edit a file at the same time โ†’ the file gets corrupted
  • With a lock: when one person edits, others must wait

Thatโ€™s the intuitive idea behind a โ€œlock.โ€


โš™๏ธ 2. Types of Locks in Java โ€‹

Java provides multiple locking mechanismsโ€”from language-level features to library-level APIs:

LevelMechanismDescription
Syntax levelsynchronizedThe most common keyword (implicit lock)
API leveljava.util.concurrent.locks.LockExplicit lock (e.g., ReentrantLock)
Atomic classesjava.util.concurrent.atomic.*Lock-free (CAS-based optimistic lock)

Letโ€™s explore them one by one ๐Ÿ‘‡


๐Ÿงฑ 1๏ธโƒฃ synchronized โ€” The Intrinsic (Monitor) Lock โ€‹

synchronized is the classic synchronization mechanism. Simple usage:

java
synchronized (obj) {
    // critical section
}

It relies on a Monitor lock inside the object header, which is a type of pessimistic lock (explained later).

You can also use it on methods:

java
public synchronized void add() { ... }

At the bytecode level, the compiler generates monitorenter and monitorexit instructions.


โš™๏ธ 2๏ธโƒฃ Lock Interface and Implementations (Explicit Locks) โ€‹

Introduced in JDK 1.5: java.util.concurrent.locks.Lock. It provides more flexibility than synchronized:

java
Lock lock = new ReentrantLock();
lock.lock();
try {
    // critical section
} finally {
    lock.unlock();
}

Advantages:

  • Can attempt to acquire a lock (tryLock())
  • Can acquire interruptibly (lockInterruptibly())
  • Supports fair and unfair locking

Lock implementations are usually built on top of AQS (AbstractQueuedSynchronizer).


๐Ÿ’ก 3๏ธโƒฃ CAS (Compare-And-Swap) and Atomic Classes โ€‹

CAS is a lock-free mechanism, based on optimistic locking.

Example:

java
AtomicInteger i = new AtomicInteger(0);
i.incrementAndGet(); // internally uses CAS

CAS is a hardware-level atomic instruction: It compares a current value in memory with an expected value, and updates only if they match; otherwise, it retries.


๐Ÿง  3. Lock Classifications (Important!) โ€‹

When discussing Java locks, youโ€™ll often hear about:

Pessimistic vs Optimistic Locks Fair vs Unfair Locks Reentrant vs Non-reentrant Locks Read/Write Locks Spin Locks

Letโ€™s clarify them ๐Ÿ‘‡


๐Ÿ”’ 1๏ธโƒฃ Pessimistic Lock โ€‹

  • Assumes conflicts are likely, so it locks first, then operates.
  • Typical examples: synchronized, ReentrantLock

Example:

java
synchronized (this) {
    count++;
}

Other threads must wait for the lock to be released. Safe but potentially slow.


๐Ÿ˜Š 2๏ธโƒฃ Optimistic Lock โ€‹

  • Assumes conflicts are rare, so it operates first, then checks.
  • If a conflict occurs, it retries.

Implemented via CAS (Compare-And-Swap)

Simplified example:

java
while (true) {
    int oldValue = atomicInt.get();
    int newValue = oldValue + 1;
    if (atomicInt.compareAndSet(oldValue, newValue)) {
        break; // success
    }
    // otherwise retry
}

โœ… Advantages: High performance (no blocking) โš ๏ธ Drawback: Under high contention, frequent retries can waste CPU cycles.


๐Ÿงญ 3๏ธโƒฃ Fair vs Unfair Locks โ€‹

  • Fair lock: Threads acquire the lock in the order they requested it.
  • Unfair lock: Threads can โ€œjump the queue,โ€ improving throughput.

ReentrantLock defaults to unfair, but you can specify:

java
new ReentrantLock(true); // fair lock

๐Ÿ” 4๏ธโƒฃ Reentrant Lock โ€‹

A lock is reentrant if the same thread can acquire it multiple times without deadlocking.

Example:

java
public synchronized void a() {
    b(); // re-enters the same lock
}
public synchronized void b() { }

Both synchronized and ReentrantLock are reentrant.


๐Ÿ“š 5๏ธโƒฃ Read/Write Lock โ€‹

When reads greatly outnumber writes, ReadWriteLock improves concurrency:

  • Multiple threads can read simultaneously
  • Writes are exclusive

Example:

java
ReadWriteLock rwLock = new ReentrantReadWriteLock();
rwLock.readLock().lock();
...
rwLock.writeLock().lock();

๐Ÿ” 6๏ธโƒฃ Spin Lock โ€‹

A spin lock doesnโ€™t suspend a thread while waiting for a lock. Instead, it loops repeatedly checking if the lock is available.

This can reduce context switching overhead under low contention.

Javaโ€™s CAS operations embody this โ€œspinningโ€ concept.


๐Ÿ“Š 4. Relationship and Evolution of Locks (Summary Diagram) โ€‹

Lock hierarchy:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ synchronized (pessimistic, intrinsic) โ”‚
โ”‚ ReentrantLock (explicit, reentrant)   โ”‚
โ”‚ ReadWriteLock (fine-grained)          โ”‚
โ”‚                                       โ”‚
โ”‚ โ†’ AQS (underlying framework)          โ”‚
โ”‚ โ†’ CAS (hardware-level instruction)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ†‘
         โ””โ”€ Optimistic Locking (CAS-based)

โšก 5. One-Line Summary Table โ€‹

TypeDescriptionTypical Implementations
PessimisticLocks first, prevents conflictssynchronized, ReentrantLock
OptimisticOperate first, check & retryAtomicInteger, CAS
FairFIFO lock acquisitionReentrantLock(true)
UnfairAllows lock jumpingReentrantLock(false)
ReentrantSame thread can re-locksynchronized, ReentrantLock
Read/WriteRead shared, write exclusiveReentrantReadWriteLock

Just something casual. Hope you like it.