Understanding Java Synchronized Mechanism and Monitor Objects

Core Concepts

Consider two independent threads operating on a shared variable: one performing 5000 increments and the other performing 5000 decrements. The final result is unpredictable due to interleaved arithmetic operations in multithreaded execution.

Critical Section: Code segments where multiple threads read and write shared resources.

Race Condition: Unpredictable outcomes occurring when multiple threads execute within a critical section due to varying code execution sequences.

Preventing Race Conditions in Java:

  • Blocking solutions: synchronized, Lock
    • synchronized provides mutual exclusion via object locks
  • Non-blocking solutions: atomic variables

Synchronized Usage Patterns

synchronized (lockObject) {
    criticalSection;
}

Basic Implementation

public class CounterDemo {
    private static int sharedCounter = 0;
    private static final Object syncLock = new Object();
    
    public static void main(String[] args) throws InterruptedException {
        Thread incrementer = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                synchronized (syncLock) {
                    sharedCounter++;
                }
            }
        });
        
        Thread decrementer = new Thread(() -> {
            for (int i = 0; i < 5000; i++) {
                synchronized (syncLock) {
                    sharedCounter--;
                }
            }
        });
        
        incrementer.start();
        decrementer.start();
        incrementer.join();
        decrementer.join();
        System.out.println("Final counter value: " + sharedCounter);
    }
}

Key Points:

  • Both synchronized blocks must reference the same lock object
  • Single synchronization point cannot prevent race conditions

Method-Level Synchronization

Instance method synchronization:

class ExampleClass {
    public synchronized void syncMethod() {
        // Synchronized on 'this'
    }
}

Static method synchronization:

class ExampleClass {
    public static synchronized void staticSyncMethod() {
        // Synchronized on ExampleClass.class
    }
}

Thread Safety Analysis

Local Variables

  • Local variables are thread-safe (stack-frame isolated)
  • Referenced objects may not be thread-safe if they escape method scope

Static Variables

  • Thread-safe if not shared or only read by multiple threads

Common Thread-Safe Classes

String, Integer, StringBuffer, Random, Vector, Hashtable, java.util.concurrent classes

Thread-safe classes provide atomic method execution but method combinations may not be atomic.

Immutable Classes

String and Integer achieve thread safety through immutability. Methods like replace() and substring() return new instances rather than modifying existing ones.

Monitor Object Structure

Java object headers consist of:

  • Mark Word: Contains object metadata including lock state
  • Klass Word: Pointer to object's class definition
  • Array Length: Present only for array objects

Monitor Mechanism

Each Java object can associate with a Monitor object. When synchronized is used, the object's Mark Word points to its Monitor. The Monitor maintains:

  • Owner: Thread currently holding the lock
  • EntryList: Queue of blocked threads waiting for the lock

Synchronized Bytecode Representation

monitorenter  // Lock acquisition
critical section code
monitorexit   // Lock release
exception handler

Advanced Locking Mechanisms

Lightweight Locks

Optimized for scenarios where threads acquire locks at different times without contention. Uses stack-based lock records instead of Monitor objects.

Locking Process:

  1. Create lock record in thread stack
  2. CAS operation to set object's Mark Word to lock record address
  3. Handle lock re-entry through addditional lock records

Lock Inflation

Occurs when lightweight lock contention happens. Converts lightweight lock to heavyweight Monitor lock.

Spin Optimization

Threads attempting to acquire contended locks briefly spin before blocking, reducing conteext switch overhead on multi-core systems.

Biased Locks

Optimization for frequently locked objects by single threads. Stores thread ID in Mark Word to avoid CAS operations on re-entry.

Biased Lock States:

  • Normal (001): No bias
  • Biased (101): Thread ID stored in Mark Word
  • Lightweight Locked (00): Lock record pointer
  • Heavyweight Locked (10): Monitor pointer

Bias Revocation Conditions

  1. Object's hashCode() method invocation
  2. Contention from other threads
  3. wait()/notify() method calls

Tags: java multithreading Synchronization Concurrency monitor

Posted on Thu, 15 Oct 2026 16:52:28 +0000 by steve012345