두 개 이상의 스레드가 서로 다른 스레드가 보유한 자원을 기다리며 무한히 대기하는 상태이다.
실제 상황 예시1
실제 상황 예시2
해결 방법:
public class DeadlockExample {
private final Object lock1 = new Object(); // 첫 번째 락 객체
private final Object lock2 = new Object(); // 두 번째 락 객체
// 첫 번째 작업 메서드
public void operation1() {
synchronized (lock1) { // 첫 번째 락을 획득
System.out.println("Operation 1: Acquired lock1...");
// ... (여기서 어떤 작업을 수행)
synchronized (lock2) { // 두 번째 락을 획득
System.out.println("Operation 1: Acquired lock2...");
// ... (여기서 어떤 작업을 수행)
}
}
}
// 두 번째 작업 메서드
public void operation2() {
synchronized (lock2) { // 두 번째 락을 획득
System.out.println("Operation 2: Acquired lock2...");
// ... (여기서 어떤 작업을 수행)
synchronized (lock1) { // 첫 번째 락을 획득
System.out.println("Operation 2: Acquired lock1...");
// ... (여기서 어떤 작업을 수행)
}
}
}
// 메인에서 실행한다.
public static void main(String[] args) {
DeadlockExample example = new DeadlockExample();
Thread t1 = new Thread(() -> example.operation1());
Thread t2 = new Thread(() -> example.operation2());
t1.start();
t2.start();
}
}
t1
, t2
)가 각각 **operation1()
**과 operation2()
메서드를 실행한다. **operation1()
**은 **lock1
**을 먼저 획득하고, 그 다음에 **lock2
**를 획득하려고 시도한다. 반면에 **operation2()
**는 **lock2
**를 먼저 획득하고, 그 다음에 **lock1
**을 획득하려고 시도한다.t1
**이 **lock1
**을 획득하고, 거의 동시에 **t2
**가 **lock2
**를 획득한다면, 두 스레드는 서로가 가진 락을 획득하려고 대기하게 된다. 이렇게 되면 두 스레드는 무한히 대기하게 되어 데드락(Deadlock) 상태에 빠진다.public class RaceConditionExample {
// 공유 자원
private int sharedResource = 0;
// 공유 자원을 1 증가시키는 메서드
public void increment() {
int temp = sharedResource; // 현재 공유 자원의 값을 임시 변수에 저장
temp = temp + 1; // 임시 변수 값을 1 증가
sharedResource = temp; // 증가된 값을 다시 공유 자원에 저장
}
public static void main(String[] args) {
RaceConditionExample example = new RaceConditionExample(); // 클래스 인스턴스 생성
// 첫 번째 스레드. 1000번 공유 자원을 증가시킴
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
// 두 번째 스레드. 1000번 공유 자원을 증가시킴
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
t1.start(); // 첫 번째 스레드 시작
t2.start(); // 두 번째 스레드 시작
try {
t1.join(); // 첫 번째 스레드가 종료될 때까지 대기
t2.join(); // 두 번째 스레드가 종료될 때까지 대기
} catch (InterruptedException e) {
e.printStackTrace();
}
// 최종 공유 자원의 값 출력
System.out.println("Final value of sharedResource: " + example.sharedResource);
}
}
t1
, t2
)가 거의 동시에 increment()
메서드를 호출하여 **sharedResource
**를 증가시킨다. 이로 인해 레이스 컨디션(Race Condition)이 발생할 수 있다.t1
**이 **sharedResource
**를 읽고 증가시킨 뒤에 **t2
**가 동일한 작업을 수행하면, 두 스레드가 거의 동시에 같은 값을 읽어 결국 하나의 증가만 반영될 수 있다. 이러한 상황을 레이스 컨디션이라고 한다.