카테고리 없음

자바의 데드락

백봉 2023. 4. 12. 09:56

자바 데드락

자바는 멀티스레딩 구조를 가지고 있어서 동시에 여러 가지 작업을 처리할 수 있습니다. 하지만 이로 인해 발생하는 문제중 하나가 데드락입니다. 데드락은 두 개 이상의 스레드가 자원을 서로 무한정 기다리는 현상을 의미합니다. 즉, 각 스레드가 서로 부족한 자원을 가지고 있으며 서로의 자원을 기다리고 있는 상태를 말합니다. 이 상황에서 스레드들은 무한정 기다리기 때문에 프로그램은 더 이상 진행할 수 없게 됩니다.

데드락의 예

예를 들어, 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 이용 중");
            }
         }
      }
   } 
}

결론

데드락은 멀티스레딩 환경에서 언제든 발생할 수 있는 문제입니다. 데드락이 발생하면 프로그램이 멈추기 때문에 어려운 문제입니다. 다양한 방법으로 데드락 방지 및 회피 기술을 익혀야 합니다. 스레드 관련 프로그래밍에서 데드락은 항상 염두에 두어야 합니다.


이미지