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: returnThe 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
