레이스 컨디션 (Race Condition)
레이스 컨디션(Race Condition)은 멀티스레드 환경에서 발생할 수 있는 동시성 문제입니다. 레이스 컨디션은 여러 스레드가 공유된 자원에 동시에 접근하여 값을 변경하려고 할 때 발생합니다. 이때 어떤 스레드가 먼저 자원에 접근하느냐에 따라 예상치 못한 결과가 발생할 수 있습니다.
예시 코드
아래는 레이스 컨디션을 보여주는 간단한 예시 코드입니다.
public class Counter {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class RaceConditionDemo {
public static void main(String[] args) {
Counter counter = new Counter();
Runnable runnable = () -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
};
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + counter.getCount());
}
}
위 코드는 Counter
클래스에서 count
변수를 갖고 있으며, increment()
메소드로 값을 증가시킵니다. RaceConditionDemo
클래스에서는 두 개의 스레드를 생성하여 increment()
메소드를 호출하는데, 이때 count
변수에 대한 접근은 동시에 이루어집니다.
두 스레드가 동시에 increment()
메소드를 호출하면, count
변수가 동시에 증가하는 상황이 발생할 수 있습니다. 이로 인해 실제로 예상한 결과와 다른 값이 출력될 수 있습니다.
스레드 동작 순서
레이스 컨디션 문제는 스레드의 동작 순서에 따라 발생할 수 있습니다. 동시에 접근할 때 순서에 따라 값이 달라지는 것을 방지하려면 동기화(synchronization)를 사용해야 합니다.
위 예시 코드에서는 synchronized
키워드를 이용하여 increment()
메소드를 동기화하고 있습니다. 동기화를 사용하면 한 스레드가 increment()
메소드를 실행하는 동안 다른 스레드는 대기 상태에 있게 됩니다.
public synchronized void increment() {
count++;
}
이와 같이 동기화를 사용하면 스레드들이 순차적으로 increment()
메소드를 호출하게 되므로 레이스 컨디션 문제를 방지할 수 있습니다.