자바 데드락
자바는 멀티스레딩 구조를 가지고 있어서 동시에 여러 가지 작업을 처리할 수 있습니다. 하지만 이로 인해 발생하는 문제중 하나가 데드락입니다. 데드락은 두 개 이상의 스레드가 자원을 서로 무한정 기다리는 현상을 의미합니다. 즉, 각 스레드가 서로 부족한 자원을 가지고 있으며 서로의 자원을 기다리고 있는 상태를 말합니다. 이 상황에서 스레드들은 무한정 기다리기 때문에 프로그램은 더 이상 진행할 수 없게 됩니다.
데드락의 예
예를 들어, A 스레드는 B 스레드에서 사용하기 위한 자원 A를 가지고 있고 B 스레드는 A 스레드에서 사용하기 위한 자원 B를 가지고 있습니다. 그리고 A 스레드에서는 자원 B가 해제될 때까지 기다리고, B 스레드에서는 자원 A가 해제될 때까지 기다리고 있습니다. 이러한 상황에서 두 스레드가 무한정 기다리는 것을 데드락이라고 합니다.
데드락을 해결하는 방법
데드락의 해결하기 위해선 다음과 같이 해결할 수 있습니다.
1. 락 순서에 의한 데드락 방지 : 락 획득 순서를 정해놓고 그 순서에 맞게 락을 획득하도록 합니다.
2. 우선순위에 의한 데드락 방지 : 높은 우선순위의 스레드가 먼저 락을 획득하도록 합니다.
3. 타임아웃에 의한 데드락 방지 : 특정 시간내에 락을 획득하지 못하면 락을 해제하도록 합니다.
4. 교착상태 회피 알고리즘을 적용하는 방식 : 다익스트라 알고리즘 등 회피 알고리즘을 이용하여 데드락을 방지합니다.
데드락 예제
public class DeadlockExample {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadA t1 = new ThreadA();
ThreadB t2 = new ThreadB();
t1.start();
t2.start();
}
private static class ThreadA extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("ThreadA: Lock1 이용 중");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
synchronized (Lock2) {
System.out.println("ThreadA: Lock1과 Lock2 이용 중");
}
}
}
}
private static class ThreadB extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("ThreadB: Lock2 이용 중");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
synchronized (Lock1) {
System.out.println("ThreadB: Lock2와 Lock1 이용 중");
}
}
}
}
}
결론
데드락은 멀티스레딩 환경에서 언제든 발생할 수 있는 문제입니다. 데드락이 발생하면 프로그램이 멈추기 때문에 어려운 문제입니다. 다양한 방법으로 데드락 방지 및 회피 기술을 익혀야 합니다. 스레드 관련 프로그래밍에서 데드락은 항상 염두에 두어야 합니다.
