자바 동시성-교착 상태
교착 상태는 둘 이상의 스레드가 서로를 기다리면서 영원히 차단되는 상황을 나타냅니다. 교착 상태는 여러 스레드가 동일한 잠금을 필요로하지만 다른 순서로 획득 할 때 발생합니다. Java 다중 스레드 프로그램은 다음과 같은 이유로 교착 상태가 발생할 수 있습니다.synchronized키워드는 지정된 개체와 관련된 잠금 또는 모니터를 기다리는 동안 실행 스레드가 차단되도록합니다. 여기에 예가 있습니다.
예
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
위의 프로그램을 컴파일하고 실행하면 교착 상태가 발생하고 다음은 프로그램에서 생성 된 출력입니다.
산출
Thread 1: Holding lock 1...
Thread 2: Holding lock 2...
Thread 1: Waiting for lock 2...
Thread 2: Waiting for lock 1...
위의 프로그램은 진행할 위치에있는 스레드 중 어느 것도 서로 잠금을 해제 할 때까지 기다리지 않기 때문에 영원히 중단됩니다. 따라서 Ctrl + C를 눌러 프로그램을 종료 할 수 있습니다.
교착 상태 솔루션 예
두 스레드가 여전히 서로를 기다리는 지 확인하기 위해 동일한 프로그램의 잠금 및 실행 순서를 변경해 보겠습니다.
예
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
따라서 잠금 순서를 변경하는 것만으로도 프로그램이 교착 상태에 빠지는 것을 방지하고 다음과 같은 결과로 완료됩니다.
산출
Thread 1: Holding lock 1...
Thread 1: Waiting for lock 2...
Thread 1: Holding lock 1 & 2...
Thread 2: Holding lock 1...
Thread 2: Waiting for lock 2...
Thread 2: Holding lock 1 & 2...
위의 예는 개념을 명확하게하기위한 것이지만 복잡한 개념이므로 교착 상태 상황을 처리하기위한 응용 프로그램을 개발하기 전에 자세히 살펴 봐야합니다.