ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java Multithreading] DeadLock 해결 방안 1 - 순환 대기 회피
    Java/Multi Threading 기초 2022. 12. 15. 12:46

    Java Multithreading

    멀티스레딩의 개념과 Java에서의 활용법을 공부하고 정리하는 시리즈입니다.


    안녕하세요! 이번 포스팅에서는 앞서 이야기했던 Deadlock이 일어나는 상황을 회피하기 위해 deadlock의 조건을 깨뜨리는 기법을 살펴보려고 합니다. 오늘 소개할 방법은 아주 간단하기 때문에, 간단한 수도코드 예제를 들어 설명을 하도록 하겠습니다.

    순환 대기 (환형 대기, Circular wait) 깨뜨리기

    순환 대기 상황을 코드로 설명해보겠습니다. 두 개의 수도코드가 등장합니다.

    // CODE 1
    lock(A);
      lock(B);
        delete(A);
        add(B);
      unlock(B);
    unlock(A);
    
    // CODE 2
    lock(B);
      lock(A);
        delete(B);
        add(A);
      unlock(A);
    unlock(B);

    코드1과 코드2는 거의 같은 형태의 코드입니다. 다만 락 객체의 순서만 조금 다를 뿐이죠.
    그런데 만약 두 코드를 각각 다른 스레드로 실행한다고 하면 어떨까요? 무조건 데드락이 일어나는 것은 아니지만, 매우 높은 확률로 데드락이 일어날 것입니다.
    순환 대기 상태를 확인하기 위해 중요한 부분은 여러 코드라인 중에서도 lock(~~) 부분이에요. 저희가 코드를 실행하는 스레드라고 상상해 보시면서 다음의 코드를 보시죠.

    1. lock(A); // CODE1의 코드가 실행
    2. lock(B); // CODE2의 코드가 실행
    3. lock(A); // CODE2의 코드를 실행하려고 했으나, A객체는 이미 락킹 상태므로 대기 상태.
    4. lock(B); // CODE1의 코드를 실행하려고 했으나, B객체는 이미 락킹 상태므로 대기 상태.
    5. // circular wait으로 인한 데드락 발생! : CODE1의 스레드와 CODE2의 스레드가 서로로 인해 대기 상태

    위 예제에서는 두 스레드가 서로 다른 객체에 대해 우선적으로 락을 얻고, 그 다음에 상대가 락을 얻은 객체에 접근하려고 해서 데드락에 빠지게 됩니다.

    이것의 해결책은 간단합니다. 아래의 코드처럼 락킹 순서를 동일하게 하면 됩니다.

    // CODE 1
    lock(A);
      lock(B);
    // ... (생략) ...
    
    // CODE 2
    lock(A);
      lock(B);
    // ... (생략) ...

    좀 전과 같은 순서대로 멀티스레드 프로그램이 실행된다고 가정해보고, 어떻게 해결되었는지를 생각해보겠습니다.

    1. lock(A); // CODE1의 코드가 실행
    2. lock(A); // CODE2의 코드를 실행하려고 했으나, A 객체는 이미 락킹 상태, 스레드 대기.
    3. //lock(B); // CODE2의 스레드는 대기 중이므로 실행 안됨.
    4. lock(B); // CODE1의 코드가 실행
    5. // 이후 CODE1의 스레드가 쭉쭉 실행. 작업이 완료되면 대기중이었던 CODE2의 스레드가 '2.'의 코드라인부터 실행.

    결론

    아주 간단한 방법-락킹 순서를 동일하게 맞춰주는 것만으로 데드락이 해결이 되었습니다. 이렇듯 순환종속성을 해결하는 것이 데드락을 해결하는 많은 방법 중 가장 간단한 해결 방법입니다.
    물론 장점만 있는 것은 아니겠죠? 락킹 할 객체의 수가 많아진다면, 또는 많은 소스코드에 락을 얻는 코드가 파편화되어 있다면 순서를 관리하기가 점점 어려워지겠죠.

    다음 시간에는 교착상태를 해결하는 다른 방법에 대해서도 알아보도록 하겠습니다.
    감사합니다! 😘

    댓글

Designed by Tistory.