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 inSharedListcan 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.