공유 자원(Shared Resource)
- 여러 프로세스나 스레드가 동시에 접근할 수 있는 시스템 자원
- 이 자원은 메모리, 파일, 데이터베이스, 프린터 등의 형태로 존재할 수 있음
- 프로세스나 스레드가 공유 자원을 동시에 접근하면 테이블 불일치나 시스템 오류가 발생할 수 있으므로 적절한 관리가 필요
경쟁 상태(Race Condition)
- 두 개 이상의 프로세스나 스레드가 동시에 공유 자원에 접근하여 그 결과가 의도하지 않은 데이터 불일치나 오류로 이어지는 상황을 의미
- 예를 들어, 두 스레드가 동시에 공유 변수의 값을 갱신하려고 할 때, 하나의 스레드가 갱신을 완료하기 전에 다른 스레드가 값을 변경하면 최종 결과가 예상과 다르게 될 수 있음
public class RaceConditionExample {
private static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter++;
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
counter++;
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Final counter value: " + counter);
}
}
임계 영역(Critical Section)
- 동시에 접근해서는 안 되는 공유 자원에 접근하는 코드 영역을 의미
- 임계 영역에서의 접근을 제어하지 않으면 경쟁 상태가 발생할 수 있음
- 따라서 임꼐 영역에서는 하나의 프로세스나 스레드만이 자원에 접근하도록 해야 함
public class CriticalSectionExample {
private static int counter = 0;
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
synchronized (lock) {
counter++;
}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
synchronized (lock) {
counter++;
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Final counter value: " + counter);
}
}