JavaRush /Java Blog /Random-KO /Java의 교착상태란 무엇입니까?
Alexey Smirnov
레벨 29
Москва

Java의 교착상태란 무엇입니까?

Random-KO 그룹에 게시되었습니다
기사를 이해하는 데 필요한 지식 수준: Java 구문 및 Java Core 퀘스트를 완료했으며 현재 Java 멀티스레딩을 학습하는 중입니다. Java의 교착 상태 또는 교착 상태는 스레드가 동기화된 개체 쌍에 대해 순환 종속성을 가질 때 발생하는 오류입니다. 한 스레드가 개체 모니터로 이동 x하고 다른 스레드가 개체 모니터로 이동한다고 상상해 보세요 y. 객체의 스레드가 x객체에 대한 동기화된 메서드를 호출하려고 시도 하고 동시에 y객체가 객체에 대한 동기화된 메서드를 호출하려고 하면 스레드가 대기 상태에 갇히게 됩니다. 다음은 교착 상태와 같은 개념에 대한 Java 문서 튜토리얼의 예입니다. 여기서 스레드 차단은 어디에서 발생합니까? yx교착 상태란 무엇입니까?  - 1
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            @Override
            public void run() {
               // System.out.println("Thread 1");
                alphonse.bow(gaston);
               // System.out.println("Th: gaston bowed to alphonse");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
              //  System.out.println("Thread 2");
                gaston.bow(alphonse);
              //  System.out.println("2.gaston waiting alph bowed");
            }
        }).start();
    }
}
여기서 이해해야 할 두 가지 중요한 사항이 있습니다.
  1. 동시에 실행되는 각 스레드는 정확히 무엇을 수행합니까?
  2. 어떤 자물쇠가 사용됩니까?
끝부터 시작합시다. 클래스의 두 객체인 및 를 생성했다고 가정 Friendalphonse보겠습니다 gaston. 그들 각각에는 자체 자물쇠가 있습니다. 따라서 이러한 잠금 장치에는 gigolos와 gaston이라는 두 가지 잠금 장치가 있습니다. 객체의 동기화된 메소드에 들어가면 해당 잠금이 잠기고, 메소드가 종료되면 해제(또는 잠금 해제)됩니다. 이제 스레드에 대해 알아보겠습니다. 첫 번째 스레드를 호출해 보겠습니다 Alphonse(객체 alphonse와 구별하기 위해 대문자를 사용). 그 기능은 다음과 같습니다( 의 약어 A로 이라고 부르겠습니다 Alphonse).
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
그리고 현재 스레드가 수행하는 작업은 다음과 같습니다 Gaston.
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
이제 이 데이터를 종합하여 답을 알아봅시다. 스레드는 서로 다른 순서로 얽힐 수 있습니다(즉, 해당 이벤트가 발생함). 예를 들어, 순서가 다음과 같은 경우 교착 상태가 작동합니다.
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
교착 상태란 무엇입니까?  - 2
이 경우 두 스레드가 모두 차단되고 각 스레드는 다른 스레드가 잠금을 해제할 때까지 기다리고 있습니다. 그러나 그들 중 누구도 이 작업을 수행하지 않을 것입니다. 왜냐하면 이를 수행하려면 메소드를 완료해야 하고 다른 스레드에 의해 차단되기 때문입니다. 그래서 그들은 그 일이 일어난 곳에 갇혀 있었습니다 deadlock. 그러나 스레드 중 하나가 두 번째 스레드가 시작되기 전에 완료될 시간을 갖는 또 다른 직조도 가능합니다.
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
이 경우 스레드의 상호 차단은 없습니다. 예를 들어, 다른 스레드가 실행할 시간을 가질 수 있도록 하는 일부 메서드가 추가되었습니다. 결과가 동시에 발생하는 이벤트의 순서(계획된 순서 또는 실행 속도)에 따라 달라지는 경우 이러한 프로세스를 러시아어로 "경쟁 조건"이라고 합니다. 모든 경쟁 조건이 잠재적으로 교착 상태를 일으키는 것은 아니지만 내 경험상 오직 경쟁 조건만이 교착 상태를 유발합니다. 답변자: Dave Lillethun
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION