Example: Synchronizing on a Different Object
Sometimes, instead of synchronizing on this
, we lock a different object to control access to a shared resource.
Scenario
- We have two threads modifying a shared
List
, but we synchronize on a separate lock object (lock
), notthis
. - This allows more fine-grained control, especially if we don’t want to block the entire object.
Code Example
import java.util.ArrayList;
import java.util.List;
class SharedList {
private final List<Integer> numbers = new ArrayList<>();
private final Object lock = new Object(); // Separate lock object
void addNumber(int num) {
synchronized (lock) { // Locking on 'lock', not 'this'
numbers.add(num);
System.out.println(Thread.currentThread().getName() + " added " + num);
}
}
void printNumbers() {
synchronized (lock) { // Ensuring consistent read
System.out.println(Thread.currentThread().getName() + " - List: " + numbers);
}
}
}
public class SyncOnAnotherObject {
public static void main(String[] args) {
SharedList sharedList = new SharedList();
Runnable task1 = () -> {
for (int i = 1; i <= 3; i++) {
sharedList.addNumber(i);
}
sharedList.printNumbers();
};
Thread t1 = new Thread(task1, "Thread-1");
Thread t2 = new Thread(task1, "Thread-2");
t1.start();
t2.start();
}
}
How This Works
- Synchronization is on
lock
(a separate object), not onthis
. - Multiple methods (
addNumber()
andprintNumbers()
) use the same lock to ensure safe modifications tonumbers
. - Benefits:
- Prevents race conditions while modifying
numbers
. - Does not block the entire object (
this
), so other unrelated methods inSharedList
can run without waiting.
- Prevents race conditions while modifying
Possible Output (Thread-Safe Execution)
Thread-1 added 1
Thread-1 added 2
Thread-1 added 3
Thread-1 - List: [1, 2, 3]
Thread-2 added 1
Thread-2 added 2
Thread-2 added 3
Thread-2 - List: [1, 2, 3, 1, 2, 3]
✔ Each thread safely modifies numbers
without corrupting data.
Why Not Use synchronized(this)
?
If we had used synchronized(this)
, other synchronized methods on this
would also be blocked, even if they didn’t modify numbers
.
By synchronizing on a separate lock (lock
), we only block access to numbers
, while allowing other operations in SharedList
to execute freely.