Mastering Java Synchronization: Object vs Class Locks Explained
This guide explains Java's synchronized keyword, detailing how object‑level and class‑level locks work, provides code examples for each, and lists essential best‑practice tips and common pitfalls to avoid when writing thread‑safe Java code.
Object‑Level Lock
Object‑level locking synchronizes non‑static methods or blocks so that only one thread can execute the code on a given instance, ensuring thread safety for instance data. It can be applied in three ways:
Declare the method with synchronized.
Wrap a code block with synchronized(this).
Synchronize on a dedicated final object field, e.g., private final Object lock = new Object(); and use synchronized(lock).
public class DemoClass {
public synchronized void demoMethod() {
// do something
}
}
public class DemoClass {
public void demoMethod() {
synchronized(this) {
// do something
}
}
}
public class DemoClass {
private final Object lock = new Object();
public void demoMethod() {
synchronized(lock) {
// do something
}
}
}Class‑Level Lock
Class‑level locking prevents multiple threads from entering synchronized blocks across all instances of a class. It is typically used for static methods or when a lock on the Class object is required.
Declare a static method with synchronized.
Synchronize on DemoClass.class inside a non‑static method.
Use a static final lock object, e.g., private static final Object lock = new Object();, and synchronize on it.
public class DemoClass {
public static synchronized void demoMethod() {
// do something
}
}
public class DemoClass {
public void demoMethod() {
synchronized(DemoClass.class) {
// do something
}
}
}
public class DemoClass {
private static final Object lock = new Object();
public void demoMethod() {
synchronized(lock) {
// do something
}
}
}Important Notes
The synchronized keyword guarantees that no two threads can execute code protected by the same lock simultaneously. synchronized can only be used with methods or code blocks, which may be static or non‑static.
When a thread enters a synchronized method or block it acquires the lock; the lock is released automatically when the thread exits, even if an exception occurs. synchronized is re‑entrant: a thread holding a lock can call another synchronized method that requires the same lock without deadlocking.
If the lock object is null, a NullPointerException is thrown at runtime.
Improper use of synchronization can degrade application performance.
Static and non‑static synchronized methods can run concurrently because they lock different objects.
According to the Java Language Specification, synchronized must not be used in constructors.
Never synchronize on a non‑final field, as its reference may change, breaking the lock guarantee.
Avoid synchronizing on String literals because they may be shared across the JVM, leading to unexpected deadlocks; instead, create a private lock object with new Object() and synchronize on it.
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.
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.
