Why Do We Need Parentheses in synchronized()
?
In Java, the synchronized
keyword requires an object reference inside parentheses (synchronized(obj)
) because it tells Java which object’s monitor (lock) to use for synchronization.
1. What Happens When We Use synchronized(object)
?
When we write:
synchronized (someObject) {
// critical section
}
- Java locks the specified object (
someObject
). - Only one thread can execute this block for the given
someObject
at a time. - Other threads that try to enter a block synchronized on the same object will wait.
Example: Synchronizing on a Specific Object
class SharedResource {
void printNumbers() {
synchronized (this) { // Locking the current instance
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
}
}
}
public class SyncExample {
public static void main(String[] args) {
SharedResource obj = new SharedResource();
Thread t1 = new Thread(obj::printNumbers, "Thread-1");
Thread t2 = new Thread(obj::printNumbers, "Thread-2");
t1.start();
t2.start();
}
}
Output (Thread Execution is Synchronized)
Thread-1 - 1
Thread-1 - 2
Thread-1 - 3
Thread-2 - 1
Thread-2 - 2
Thread-2 - 3
✔ Since both threads use the same object (obj
), the second thread waits until the first thread finishes.
2. Why Can’t We Just Type synchronized
Without Parentheses?
If Java allowed:
synchronized {
// Critical section
}
- What would be synchronized?
- Java needs to know which object should be locked.
- Without specifying an object, Java has no way to decide which threads should block.
Synchronization Needs an Object to Lock
Java’s synchronization mechanism works by acquiring a lock on an object’s monitor. If you don’t specify an object, Java wouldn’t know which lock to use.
3. Alternative: synchronized
Methods (No Parentheses)
Instead of synchronizing a block, you can synchronize an entire method using synchronized
without parentheses:
class SharedResource {
synchronized void printNumbers() { // Locks 'this' (current object)
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
}
}
Why No Parentheses Here?
- The
synchronized
keyword automatically locks the current object (this
). - It’s equivalent to writing: javaCopyEdit
void printNumbers() {
synchronized (this) { // Implicit locking on 'this'
// Code
}
}
4. Synchronizing on a Class-Level Lock (static synchronized
)
If a method is static, synchronization uses the class object (ClassName.class
):
class SharedResource {
static synchronized void printNumbers() { // Locks the class itself
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
}
}
✔ Equivalent to:
static void printNumbers() {
synchronized (SharedResource.class) {
// Code
}
}
- This ensures only one thread accesses this method across all instances of the class.
Final Thoughts
Syntax | What It Locks | Use Case |
---|---|---|
synchronized (obj) {} | The specific object | Synchronizing a part of code inside an object |
synchronized (this) {} | The current instance | Synchronizing an instance method or block |
synchronized (ClassName.class) {} | The class itself | Synchronizing static methods or class-level resources |
synchronized void method() {} | The current instance | Synchronizing an entire method (no parentheses needed) |
static synchronized void method() {} | The class itself | Synchronizing a static method |
✔ Parentheses are needed in synchronized(obj)
to specify which object should be locked.
✔ synchronized
without parentheses is only valid for entire methods, where it implicitly locks this
(for instance methods) or the class (for static methods).