Thread synchronization is a mechanism that controls access to shared resources when multiple threads are running concurrently. Its primary purpose is to ensure that only one thread can execute a critical section of code at a time, preventing data inconsistency and maintaining thread safety.
Key Points: • Synchronization prevents race conditions when multiple threads access shared data. • It ensures data consistency and predictable application behavior. • Java provides synchronization using synchronized methods, synchronized blocks, locks, and concurrent utilities. • Only one thread can access a synchronized resource at a given time. • Synchronization is essential in multi-threaded applications that share mutable data.
Why Is Synchronization Important?
Consider a shared bank account balance:
Initial Balance:
1000
Thread 1:
Deposit 500
Thread 2:
Withdraw 200
Without synchronization:
• Both threads may read the same balance simultaneously. • One update may overwrite the other. • The final balance may become incorrect.
This issue is known as a Race Condition.
How Synchronization Solves the Problem
Synchronization ensures:
1. One thread enters the critical section. 2. Other threads wait until the lock is released. 3. Shared data remains consistent.
Example:
Without Synchronization
Thread 1 → Read Balance = 1000
Thread 2 → Read Balance = 1000
Thread 1 → Update Balance = 1500
Thread 2 → Update Balance = 800
Incorrect Result:
800
With Synchronization
Thread 1 → Complete Update
Thread 2 → Perform Update
Correct Result:
1300
Code Example:
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class Demo {
public static void main(String[] args)
throws InterruptedException {
Counter counter = new Counter();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(
counter.getCount());
}
}Output:
2000
Without synchronization, the result may be less than 2000 due to race conditions.
Ways to Achieve Synchronization in Java
1. Synchronized Method
public synchronized void update() {
// Critical section
}Locks the entire method.
2. Synchronized Block
public void update() {
synchronized (this) {
// Critical section
}
}Locks only the required code block.
3. ReentrantLock
Provides advanced locking features.
Example:
lock.lock();
try {
// Critical section
} finally {
lock.unlock();
}4. Concurrent Collections
Examples:
• ConcurrentHashMap • CopyOnWriteArrayList
Designed for thread-safe operations.
Real-World Example
Online Ticket Booking System
Multiple users try to book the last available seat.
Without Synchronization:
• Multiple bookings may succeed. • Data becomes inconsistent.
With Synchronization:
• Only one user books the seat. • Remaining users receive an unavailable message.
Benefits of Synchronization
• Prevents race conditions • Maintains data consistency • Ensures thread safety • Protects shared resources • Improves application reliability
Potential Drawbacks
• Increased waiting time for threads • Reduced parallelism • Excessive synchronization can impact performance
Therefore, synchronize only critical sections of code.
Interview Tip: A concise interview answer is:
"Thread synchronization is the process of controlling access to shared resources in a multi-threaded environment. It ensures that only one thread can execute a critical section at a time, preventing race conditions and maintaining data consistency. In Java, synchronization can be achieved using synchronized methods, synchronized blocks, locks, and concurrent collections."