Back to course

Synchronization and Thread Safety Issues

Java Mastery: From Zero to Professional Developer (50-Lesson Journey)

Lesson 47: Synchronization and Thread Safety Issues

When multiple threads access shared, mutable data simultaneously, it can lead to inconsistent results and data corruption—a condition known as a race condition.

1. The Race Condition Problem

Consider two threads trying to increment a shared counter (i++). This operation involves three steps:

  1. Read the current value of i.
  2. Increment the value.
  3. Write the new value back to i.

If Thread A reads i=10, Thread B reads i=10, both increment to 11, and both write 11 back, the final result is 11 instead of the correct 12.

2. Synchronization (The synchronized Keyword)

Synchronization is the tool used to control access to shared resources, ensuring that only one thread can execute a critical section of code at a time.

Synchronized Methods

Applying synchronized to a method locks the entire object instance. If Thread A calls a synchronized method, no other thread can enter any other synchronized method on that same object until Thread A exits.

java public class SharedCounter { private int count = 0;

// Only one thread can be inside this method at any time
public synchronized void increment() {
    count++; // Critical section
}

}

Synchronized Blocks

This is more granular. It allows synchronization only on a specific block of code, reducing contention by locking a specific object (the monitor).

java public void process() { // Non-critical operations here

synchronized (this) { // Lock only the critical section
    // Critical code that modifies shared resources
    count++; 
}

// Other non-critical operations

}

The Monitor: Every Java object has an intrinsic lock (monitor). Synchronization works by acquiring and releasing this lock.