Deep Dive into Java synchronized: Object Header, Lock Types, and JVM Implementation
This article provides a comprehensive analysis of the HotSpot JVM implementation of the synchronized keyword, covering object header layout, the three lock states (biased, lightweight, heavyweight), their acquisition and release processes, bytecode differences, and practical code examples to help readers understand Java concurrency internals.
The article introduces the two basic synchronization constructs in Java—synchronized methods and synchronized blocks—and presents a simple demo class SyncTest that prints messages inside a synchronized block and a synchronized method.
public class SyncTest { public void syncBlock(){ synchronized(this){ System.out.println("hello block"); } } public synchronized void syncMethod(){ System.out.println("hello method"); } }
Using javap -v , the article shows the generated bytecode for both the block and the method, highlighting the monitorenter and monitorexit instructions for the block and the ACC_SYNCHRONIZED flag for the method.
... // syncBlock bytecode excerpt 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 7: ldc #3 // String hello block 9: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 12: aload_1 13: monitorexit 14: goto 22 17: astore_2 18: aload_1 19: monitorexit 20: aload_2 21: athrow 22: return
The article then explains that the lock state is stored in the object header’s Mark Word, which can represent an unlocked state, biased lock, lightweight lock, or heavyweight lock. It describes how the Mark Word changes depending on the lock type and shows diagrams of the object header layout.
Next, the three lock implementations are detailed:
Heavyweight lock : uses OS mutexes (futex on Linux), with a monitor object containing contention lists, wait sets, and an owner thread.
Lightweight lock : creates a Lock Record on the thread stack, attempts to CAS the Mark Word to point to this record, and falls back to heavyweight lock on contention.
Biased lock : initially marks the object as biasable; the first thread to acquire the lock CASes the thread ID into the Mark Word. Subsequent acquisitions by the same thread require only simple pointer updates, while other threads trigger bias revocation or upgrade.
For each lock type, the article outlines the lock acquisition and release steps, including CAS operations, lock inflation, and bias revocation mechanisms such as bulk rebias and bulk revoke, which are triggered after certain thresholds.
Finally, the article summarizes that Java synchronized progresses through biased → lightweight → heavyweight lock upgrades when contention increases, and that lock downgrade is possible but rare. It notes that this is the first part of a series, with deeper source‑code analysis to follow.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.