This is an issue when a synchronized block uses a static (class-level) lock but only accesses instance fields. The rule does not apply when the synchronized block also accesses static state, because a static lock is required in that case.

Why is this an issue?

Locks in multi-threaded programming control access to shared data. When a lock protects a field, matching the lock scope to the data scope avoids unnecessary contention.

A class-level lock (a static lock) is shared across all instances of a class. It is appropriate for guarding class-level (static) fields.

An instance-level lock belongs to a specific object instance. It is appropriate for guarding instance fields.

A static lock does provide mutual exclusion and happens-before visibility for instance fields — the synchronization is correct. However, using a static lock to guard only instance fields forces all threads across all instances to serialize on a single monitor, even when they access independent data. This unnecessary contention reduces throughput without any safety benefit.

In Java, class-level locks are implemented using static fields:

private static final Object LOCK = new Object();

This creates a lock that is shared across all instances of the class.

What is the potential impact?

Using a static lock where an instance lock would suffice causes unnecessary thread contention. In applications with many instances or high thread counts, this can measurably degrade throughput and response times. The broader lock scope serializes work that could safely run in parallel, wasting CPU resources and limiting scalability.

How to fix it

When a synchronized block accesses only instance fields, replace the static lock with an instance-level lock so that each object guards its own state independently.

Do not blindly replace a static lock with an instance lock if the synchronized block accesses both instance and static state. A static lock is required in that case; removing it would leave the static state unprotected.

Code examples

Noncompliant code example

class Counter {
    private static final Object LOCK = new Object();
    private int count = 0;

    public void increment() {
        synchronized(LOCK) {  // Noncompliant: static lock guards only instance state
            count++;
        }
    }
}

Compliant solution

class Counter {
    private final Object lock = new Object();
    private int count = 0;

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

Resources

Documentation