What is the difference between race condition and data race?
sobes.tech AI
Answer from AI
Race condition — is a situation where the outcome of a program depends on the order of execution of parallel threads. Data race — a more specific term, referring to an undefined order of access (at least one write) to the same memory cell from two or more threads without proper synchronization. Data race is a type of race condition.
- Race Condition: A broader concept. Occurs when the program's logic is broken due to unpredictable interleaving of thread operations. It can be caused not only by access to shared data but also, for example, by incorrect use of external resources.
- Data Race: A specific type of race condition. Happens when there is unsynchronized concurrent access (at least one write) to the same variable from different threads. It is considered undefined behavior in the Java Memory Model.
Example of a race condition (not a data race): two threads try to create a file with the same name. The one who creates it first "wins". Example of a data race: two threads simultaneously increment an unsynchronized variable.
// Example demonstrating Data Race
public class Counter {
private int count = 0; // Shared variable
public void increment() {
count++; // Read-modify-write operation, non-atomic
}
public int getCount() {
return count;
}
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();
// Expected result: 2000, but due to data race it may be less
System.out.println("Final count: " + counter.getCount());
}
}
To prevent data races and some types of race conditions in Java, synchronization mechanisms such as synchronized, volatile, Lock, atomic variables (AtomicInteger, AtomicLong, etc.) are used.
// Example preventing Data Race using synchronized
public class SynchronizedCounter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
// ... (main method similar to above)
}