Java
synchronized block
concurrency
threading
programming concepts

What is the purpose of passing parameter to synchronized block?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Java, the expression inside a synchronized(...) block chooses the lock object that protects the code inside that block. That parameter is not an arbitrary argument. It is the monitor a thread must acquire before entering the block. Understanding that choice is crucial because synchronization only works when competing threads lock on the same object.

What the Parameter Really Means

Consider this example:

java
1Object lock = new Object();
2
3synchronized (lock) {
4    // critical section
5}

The parameter is lock. Java uses that object’s monitor as the lock for the critical section.

If one thread is already inside a block synchronized on that exact same object, another thread trying to enter a block synchronized on the same object must wait.

That is the whole purpose: define which shared monitor controls access.

Why the Choice of Object Matters

Synchronization does not magically protect data by itself. It protects access only when all relevant code agrees on the same lock object.

java
1class Counter {
2    private final Object lock = new Object();
3    private int value = 0;
4
5    public void increment() {
6        synchronized (lock) {
7            value++;
8        }
9    }
10
11    public int getValue() {
12        synchronized (lock) {
13            return value;
14        }
15    }
16}

Here both methods synchronize on the same lock, so updates and reads coordinate correctly.

If one method synchronized on lock and another synchronized on this, the protection would be inconsistent.

Common Lock Choices

You will often see these patterns:

  • 'synchronized(this) locks the current object'
  • 'synchronized(SomeClass.class) locks at the class level'
  • 'synchronized(lock) uses a dedicated private lock object'

Example with this:

java
1public void increment() {
2    synchronized (this) {
3        count++;
4    }
5}

Example with a private dedicated lock:

java
1private final Object lock = new Object();
2
3public void increment() {
4    synchronized (lock) {
5        count++;
6    }
7}

A dedicated private lock is often safer because outside code cannot accidentally lock on it.

Why Not Synchronize on Just Anything

Bad lock choices can create subtle bugs.

For example, this is risky:

java
synchronized ("shared") {
    // risky
}

String literals are interned, so unrelated code might end up sharing the same lock unexpectedly.

Likewise, synchronizing on publicly accessible objects can create accidental contention or even deadlock if external code also uses them as locks.

That is why private final lock objects are a common best practice.

Method Synchronization Is Similar

A synchronized instance method:

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

is roughly equivalent to:

java
1public void increment() {
2    synchronized (this) {
3        count++;
4    }
5}

A synchronized static method locks on the Class object instead.

So the parameter in a synchronized block gives you explicit control over what a synchronized method would otherwise choose implicitly.

Common Pitfalls

The biggest mistake is thinking the parameter is just a value to "turn synchronization on." It is specifically the lock identity.

Another issue is synchronizing on different objects while trying to protect the same shared data. That gives a false sense of safety because threads are not actually coordinating.

Some developers also synchronize on mutable references. If the lock object changes, the protection model breaks.

Finally, do not use synchronized(new Object()). A new object each time means every thread gets a different lock, so no real synchronization happens.

Summary

  • The parameter in synchronized(obj) chooses the monitor object used as the lock.
  • Synchronization works only when competing threads lock on the same object.
  • 'this, ClassName.class, and dedicated private lock objects are common choices.'
  • Dedicated private final lock objects are often the safest design.
  • Choosing the wrong lock object can silently break thread safety.

Course illustration
Course illustration

All Rights Reserved.