Deep Dive into Java Concurrency: The Source-Level Mechanics of synchronized

This article thoroughly examines Java's synchronized keyword, covering its three usage forms, the underlying bytecode instructions, how lock information is stored in the object header's Mark Word, the step‑by‑step lock upgrade process from no‑lock to heavyweight, and JVM optimizations such as lock elimination and coarsening, providing interview‑ready explanations.

Coder Trainee
Coder Trainee
Coder Trainee
Deep Dive into Java Concurrency: The Source-Level Mechanics of synchronized

Three usages of synchronized

Instance methods lock the current object, static methods lock the Class object, and synchronized blocks lock the object specified in the parentheses.

// instance method → locks this
public synchronized void instanceMethod() {
    // business code
}

// static method → locks the Class object
public static synchronized void staticMethod() {
    // business code
}

// block → locks the object in parentheses
public void blockMethod() {
    synchronized (this) {
        // business code
    }
}

Note: The lock is attached to the object, not the method; each Java object’s header stores the lock metadata.

Bytecode implementation

A synchronized block is compiled to the monitorenter and monitorexit instructions. A synchronized method carries the ACC_SYNCHRONIZED flag, so the JVM handles locking automatically.

public class SyncExample {
    public void test() {
        synchronized (this) {
            System.out.println("hello");
        }
    }
}

monitorenter : attempts to acquire the object's monitor lock.

monitorexit : releases the monitor lock (also emitted for exceptional exits).

Lock storage in the object header

Every Java object consists of an object header, instance data, and alignment padding. The lock information resides in the Mark Word of the header.

25 bits – hashcode

4 bits – GC generation age

1 bit – bias flag (0 = not biased, 1 = biased)

2 bits – lock flag (01 = no‑lock/bias, 00 = lightweight, 10 = heavyweight)

The lock flag determines the current lock state:

Lock flag 01 & bias flag 0 → no lock

Lock flag 01 & bias flag 1 → biased lock

Lock flag 00 → lightweight lock

Lock flag 10 → heavyweight lock

Lock upgrade process (JDK 1.6+)

Before JDK 1.6, synchronized always used a heavyweight OS mutex. Since JDK 1.6 the JVM upgrades locks in one direction only:

new object ──► biased lock (single thread) ─► lightweight lock (few threads) ─► heavyweight lock (high contention)

No‑lock state

When an object is created, its Mark Word contains only hashcode and age; no thread has attempted to lock it.

Biased lock

Applicable when a single thread repeatedly acquires the lock.

The JVM records the owning thread ID in the Mark Word via a CAS operation and sets the bias flag. Subsequent entries by the same thread succeed without any CAS. The bias is revoked only when another thread contends, which requires a global safepoint to pause the owning thread and upgrade or release the lock.

Release timing: The bias is revoked when another thread attempts to acquire the lock; the JVM pauses the biased thread at a safepoint, then upgrades to a lightweight lock or releases the bias.

Startup delay: The JVM delays enabling biased locking for about 4 seconds after startup to avoid frequent revocations during heavy start‑up contention.

Lightweight lock

Applicable for a few threads alternating lock acquisition.

When contention appears, the biased lock is revoked and upgraded to a lightweight lock that relies on CAS‑based spinning.

Lock acquisition steps:

Create a Lock Record in the current thread’s stack frame.

Copy the Mark Word into the Lock Record (the Displaced Mark Word ).

CAS the Mark Word to point to the Lock Record.

If CAS succeeds, the lock flag becomes 00 (lightweight).

If CAS fails, the thread begins spinning (busy‑wait).

Spinning consumes CPU but avoids blocking. Since JDK 1.7 the spin count is adaptively adjusted based on previous outcomes.

Heavyweight lock

Applicable for high‑contention scenarios.

If spinning exceeds a threshold or many threads compete, the lightweight lock upgrades to a heavyweight OS mutex. The Mark Word now stores a pointer to an ObjectMonitor and the lock flag becomes 10. Contending threads block and are scheduled by the operating system, incurring user‑mode to kernel‑mode transitions, which explains the high cost of heavyweight locks.

Other optimizations

Lock elimination

The JVM’s escape analysis can prove that a lock is never shared between threads and remove it entirely.

public String concat(String a, String b) {
    StringBuffer sb = new StringBuffer(); // does not escape
    sb.append(a);
    sb.append(b);
    return sb.toString(); // JVM eliminates the lock on StringBuffer.append
}

Lock coarsening

If the JVM detects consecutive lock/unlock pairs, it may merge them into a single broader lock, reducing the number of lock operations.

// before coarsening: each append acquires/releases a lock
for (int i = 0; i < 100; i++) {
    sb.append(i); // lock per iteration
}
// after coarsening: one lock for the whole loop
synchronized (sb) {
    for (int i = 0; i < 100; i++) {
        sb.append(i);
    }
}

Interview‑ready outline

Usage layer – three forms (instance method, static method, block).

Bytecode layer – monitorenter / monitorexit or ACC_SYNCHRONIZED flag.

JVM layer – lock metadata stored in the object header’s Mark Word.

Lock upgrade – no‑lock → biased → lightweight → heavyweight; upgrades are one‑way.

Typical scenarios – biased for single‑thread, lightweight for few threads, heavyweight for high contention.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaJVMconcurrencylocksynchronizedobject header
Coder Trainee
Written by

Coder Trainee

Experienced in Java and Python, we share and learn together. For submissions or collaborations, DM us.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.