Why Locks Matter: Deep Dive into Java’s Synchronization Mechanisms
This article explains why locks are essential for preventing dirty reads and data inconsistency, explores the principles behind volatile, synchronized, monitor, CAS, and AQS, and illustrates Java’s lock implementations, optimizations, and practical usage examples such as ConcurrentHashMap.
Why Use Locks?
Locks are used to solve dirty reads and data inconsistency caused by concurrent operations.
Basic Principles of Lock Implementation
volatile
Java allows threads to access shared variables. To ensure accurate and consistent updates, threads should obtain exclusive access to a variable, which can be achieved with the volatile keyword in many cases, offering lower overhead than synchronized.
volatile guarantees visibility of shared variables across processors, meaning a change made by one thread becomes visible to others.
Conclusion: When used correctly, volatile is cheaper than synchronized because it avoids thread context switches.
synchronized
synchronized achieves synchronization through a locking mechanism.
Every Java object can serve as a lock, manifested in three forms:
For a regular synchronized method, the lock is the current instance.
For a static synchronized method, the lock is the Class object.
For a synchronized block, the lock is the object specified in the parentheses.
A thread must acquire the lock before entering a synchronized block and must release it upon exit or exception.
synchronized Implementation Details
synchronized is built on a Monitor, which provides two capabilities:
Mutual exclusion
Cooperation
Java uses object monitors to guarantee exclusive execution of synchronized code and employs wait / notify / notifyAll for thread coordination. Both Class and Object have an associated Monitor.
Monitor workflow:
Thread enters a synchronized method.
Thread must acquire the Monitor lock; only one thread can own it at a time.
The owning thread can call wait(), releasing the lock and entering the wait set.
Other threads invoke notify() / notifyAll() to wake waiting threads, which must reacquire the lock.
When the synchronized method finishes, the thread releases the lock.
Low‑Level Implementation
Synchronized blocks compile to monitorenter and monitorexit bytecode instructions; synchronized methods are marked with the ACC_SYNCHRONIZED flag.
Bytecode example (generated by javap):
Lock Optimizations
Since Java 6, the JVM introduces biased locks and lightweight locks to reduce lock acquisition/release overhead. Locks progress through four states: no‑lock, biased, lightweight, and heavyweight. Locks can be upgraded but not downgraded.
Biased Lock
Lightweight Lock
Additional optimizations include lock coarsening, lock elimination, and adaptive spinning.
CAS (Compare‑And‑Set)
CAS is an atomic operation that updates a memory location only if its current value matches an expected value, ensuring updates are based on the latest information. It is implemented using the processor’s CMPXCHG instruction.
Advantages: low overhead when contention is low.
Disadvantages: high cost under contention, ABA problem, and only works for a single shared variable.
Java Lock Implementations
AbstractQueuedSynchronizer (AQS)
AQS provides a framework for building locks and other synchronizers.
State Representation
FIFO Queue for Thread Ordering
Threads that fail to acquire the lock create a node and append it to a FIFO double‑linked list.
When the lock is released, the head node wakes its successor, which then becomes the new head.
Exclusive vs. Shared Locks
Exclusive locks allow only one thread (e.g., ReentrantLock); shared locks allow multiple threads (e.g., CountDownLatch).
Exclusive Lock Acquisition
Shared Lock Acquisition
Lock Usage Example: ConcurrentHashMap
ConcurrentHashMap employs lock striping: the data is divided into segments, each protected by its own lock, allowing concurrent access to different segments.
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
