JVM.Threads.Explain the role of the synchronized keyword in the JVM

The Role of the synchronized Keyword in the JVM

The synchronized keyword in Java ensures thread safety by preventing multiple threads from accessing critical sections of code simultaneously. It is implemented at the JVM level using monitor locks (intrinsic locks).


1. What Does synchronized Do?

When a thread enters a synchronized method or block:

  • It acquires a lock (monitor) on the specified object.
  • No other thread can enter another synchronized block that locks the same object until the first thread exits.
  • When the thread exits, it releases the lock, allowing other threads to enter.

Example of synchronized Preventing Race Conditions

public class Counter {
    private int count = 0;

    public synchronized void increment() { // Locks on 'this'
        count++;
    }

    public synchronized int getCount() { // Locks on 'this'
        return count;
    }
}

If two threads try to execute increment() at the same time, one must wait.This prevents race conditions.

2. How Does synchronized Work in the JVM?

Internally, the JVM uses monitor locks (mutexes) to implement synchronized.

Bytecode Representation

When you write:

public synchronized void increment() { count++; }

The compiled bytecode (via javap -c) shows:

monitorenter
...
monitorexit
  • monitorenter: Acquires the lock (monitor).
  • monitorexit: Releases the lock.

💡 Each object in Java has an implicit monitor lock. The thread holding the monitor owns the lock, blocking other threads.

3. Types of synchronized in Java

1️⃣ synchronized Instance Methods

Locks on the current object (this), preventing multiple threads from accessing synchronized methods on the same instance.

public class BankAccount {
    private int balance = 100;

    public synchronized void deposit(int amount) { // Locks 'this'
        balance += amount;
    }

    public synchronized int getBalance() { // Locks 'this'
        return balance;
    }
}

Ensures atomic updates to balance.

2️⃣ synchronized Static Methods

Locks on the class object (ClassName.class), ensuring only one thread can execute any static synchronized method of the class.

public class Logger {
    public static synchronized void log(String message) {
        System.out.println(message);
    }
}

Ensures thread safety across all instances of the class.

Equivalent to:

public static void log(String message) {
    synchronized (Logger.class) { // Explicit locking
        System.out.println(message);
    }
}

3️⃣ synchronized Blocks

Allows fine-grained control, locking only a specific part of the method instead of the whole method.

public class Inventory {
    private int stock = 100;
    private final Object LOCK = new Object(); // Custom lock

    public void reduceStock() {
        synchronized (LOCK) { // Only locks this section
            if (stock > 0) {
                stock--;
            }
        }
    }
}

Better performance because it locks only the critical section.

4. When to Use synchronized?

Use synchronized when:

  • Modifying shared data across threads.
  • You need mutual exclusion (only one thread executes at a time).
  • You need simplicity (easier to read than ReentrantLock).

Avoid synchronized when:

  • You need non-blocking operations (AtomicInteger, ConcurrentHashMap).
  • You need fine-grained locking (ReentrantLock is better).

5. Limitations of synchronized

ProblemWhy?Alternative
Performance IssuesLocks block other threadsUse lock-free algorithms (AtomicInteger)
Thread ContentionToo many threads waiting for a lockUse ReentrantLock for fairness
DeadlocksIf two threads lock resources in different ordersAlways lock in a consistent order

6. Summary

TypeLocks OnBest Use Case
Instance MethodthisSynchronizing per-object operations
Static MethodClassName.classSynchronizing shared static resources
Synchronized BlockCustom objectFine-grained control, better performance
This entry was posted in Без рубрики. Bookmark the permalink.