java.lang.Thread.State 이해 : WAITING (주차)


91

첫째, 정말 멍청한 질문입니다. 대기중인 '주차'가 무엇을 의미하는지 궁금합니다. 스레드가 파킹 대기 중입니까? 아니면 방금 파킹되었으므로 대기 상태입니까? 주차가 발생하면 CPU / 메모리 리소스가 얼마나 많이 사용됩니까? 스레드 파킹의 목적은 무엇입니까?

둘째, Java Thread API 에서 park 메소드를 살펴보면

허용을 사용할 수없는 경우 스레드 스케줄링 목적으로 현재 스레드를 비활성화합니다.

허가가 사용 가능하면 소비되고 호출이 즉시 반환됩니다. 그렇지 않으면 현재 스레드가 스레드 스케줄링 목적으로 비활성화되고 세 가지 중 하나가 발생할 때까지 휴면 상태가됩니다 .....

영어가 제 모국어가 아니기 때문에 '허가'를 일종의 '스레드 파킹 허용'으로 의도했기 때문에 다음과 같은 질문을 이해하는 데 어려움이 있습니다.

  • 그 의미는 무엇이며, '허가증'은 무엇이며, 허가증을 누가 어떻게 확인하고 있습니까?
  • 그게 무슨 뜻입니까? '허가가 있으면 소비된다', '주차'되는 것입니까?
  • 다음, 두 번째 점이 사실이라면 '주차'와 '휴면'의 차이점은 무엇입니까? 허가증이 있으면 영원히 주차 할 수 있고 그렇지 않은 경우 '휴면'으로 만들 수 있습니까?

감사

답변:


37

허용은 실행을 계속할 수있는 권한을 의미합니다. 주차는 허가를받을 수있을 때까지 실행을 중단하는 것을 의미합니다.

Semaphore의 허가 와 달리 LockSupport허가는 스레드와 연관되어 있으며 (즉, 특정 스레드에 허가가 주어짐) 누적되지 않습니다 (즉, 스레드 당 허가가 하나만있을 수 있으며 스레드가 허가를 소비하면 사라집니다).

을 호출하여 스레드에 허가를 줄 수 있습니다 unpark(). 스레드는를 호출하여 허용을 사용할 수있을 때까지 (또는 스레드가 중단되거나 시간 초과가 만료되는 등) 실행을 일시 중단 할 수 있습니다 park(). 허용이 사용 가능할 때 파킹 된 스레드는이를 소비하고 park()메소드를 종료합니다 .


2
따라서 스레드 A가 스레드 B에 대해 'park'를 호출하지만 허용을 사용할 수있는 경우 ( 'B는 파킹 할 수 없음'), A의 호출은 그냥 반환되고 B는 파킹되지 않습니다. 그렇지 않으면 허가를받을 수 없을 때 B는 따라야합니다. 그래서 대기 (주차)는 "허가증이 없어서 A가 나를 주차하려고하는데 지금은 할 수 없어서 A도 막고있다"는 뜻인가요? 이 긴 문장에 대해 죄송합니다. 이 대기는 상당한 자원 소모적이라고 생각합니다. 허가증 전체를 누가 관리하고 있는지 아직도 궁금합니다. 어떤 스레드에는 허가가 있고 다른 스레드는 허가가 없다고 누가 / 무엇을 결정합니다.
레오나르도

2
@Leonardo : 스레드는 자신 만 파킹 할 수 있으며 다른 스레드는 파킹 할 수 없습니다. 따라서 호출 park()은 "다른 스레드가 호출하여 허가를받을 때까지 내 실행을 일시 중지하고 싶습니다"를 의미 unpark()합니다.
axtavt 2011 년

따라서 스레드는 다른 스레드를 파킹 할 수 없지만 다른 스레드에 의해 파킹 해제 될 수 있습니까? 그 맞습니까 ? 그렇다면 그 주차는 언제 발생합니까? 스레드는 현재 할 일이 없을 수도 있고, 계속해서 허가증을 확인하는 것입니다. 예를 들어 이것은 데몬 스레드에 적합합니다.
레오나르도

또한 WAITING (parking)은 주차 대기 중이거나 주차 후 대기 상태에 있음을 의미합니다. 죄송합니다 나는이 바보 같은 질문 :-) 알고
레오나르도

3
@Leonardo : 주차 후 대기 상태를 의미합니다.
axtavt 2011 년

11

java Thread State Documentation에 따라 스레드는 다음 세 가지 이유로 WAITING 상태가 될 수 있습니다.

  1. 제한 시간이없는 Object.wait
  2. 시간 제한없이 Thread.join
  3. LockSupport.park

스레드에서 파크 메소드를 호출하면 허용이 사용 가능하지 않는 한 스레드 스케줄링 목적으로 스레드가 비활성화됩니다. 아직 사용할 수없는 경우 unpark 메서드를 호출하여 지정된 스레드에 대한 허용을 사용할 수 있습니다.

따라서 스레드가 LockSupport.park에 의해 WAITING 모드에 있으면 WAITING (파킹)으로 표시됩니다.

현재 스레드에서만 park를 호출 할 수 있습니다. 이것은 생산자-소비자 디자인 패턴을 구현하는 데 매우 유용한 메커니즘입니다.


3

클래스 설명 ( LockSupport javadoc 맨 위에 있음 )에서 허용을 설명합니다.

이 클래스는이를 사용하는 각 스레드 인 허용 (Semaphore 클래스의 의미에서) 과 연관됩니다 . 허가증을 사용할 수있는 경우 주차 요청이 즉시 반환되어 [허가증] 을 소비 합니다. 그렇지 않으면 [ 보류 요청] 이 차단 될 수 있습니다. 아직 사용 가능하지 않은 경우 주차 해제를 호출하면 허가증을 사용할 수 있습니다. (하지만 세마포어와 달리 허가는 누적되지 않습니다. 최대 하나가 있습니다.)

( 비영어권 사용자가 읽기 쉽도록 [텍스트] 를 확장했습니다 .)

더 깊은 이해를 가진 누군가가 이것에 대해 자세히 설명 할 수 있기를 바랍니다. axtavt의 답변을 참조하십시오.

마지막으로, javadoc의 마지막 인용문 :

이러한 방법은 더 높은 수준의 동기화 유틸리티를 만들기위한 도구로 사용되도록 설계되었으며 대부분의 동시성 제어 응용 프로그램에는 그 자체로 유용하지 않습니다.


3

문서를 읽는 동안 해결할 수 없었던이 질문을 다시 검토하게 만든 부분은 다음과 같습니다.

허가증이 있으면 소비되고 즉시 전화가 돌아옵니다 ...

그래서 경우에 허가 (permit)가 "가능"이며, 누구어떻게 즉시 소비 얻을 수 그래서, 그것을 사용할 수 있도록? 이것은 어떻게 든 찾기가 쉽지 않았습니다.

public static void main(String[] args) {

    Thread parkingThread = new Thread(() -> {
        System.out.println("Will go to sleep...");
        sleepTwoSeconds();
        System.out.println("Parking...");
        // this call will return immediately since we have called  LockSupport::unpark
        // before this method is getting called, making the permit available
        LockSupport.park();
        System.out.println("After parking...");
    });

    parkingThread.start();

    // hopefully this 1 second is enough for "parkingThread" to start
    // _before_ we call un-park
    sleepOneSecond();
    System.out.println("Un-parking...");
    // making the permit available while the thread is running and has not yet
    // taken this permit, thus "LockSupport.park" will return immediately
    LockSupport.unpark(parkingThread);

}

private static void sleepTwoSeconds() {
    try {
        Thread.sleep(1000 * 2);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

private static void sleepOneSecond() {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}    

코드는 자체적으로 말하고 thread는 실행 중이지만 아직 호출 되지 않은LockSupport.park 반면 다른 스레드는이 LockSupport.unpark를 호출 하므로 허용을 사용할 수 있습니다. 그 후 우리는 전화LockSupport.park 하면 허가가 가능하기 때문에 즉시 반환됩니다.

당신이 그것에 대해 생각하면 당신은 당신이 통제하지 않는 일부 코드와 그 코드 호출에 스레드를 노출하는 경우, 이것은 조금 위험 LockSupport.unpark하면 잠시 park그 이후 - 그것은 작동하지 않을 수 있습니다.


아주 좋은 점은 허가를주는 활동 (즉, unpark () 호출)은 스레드가 파킹 될 때만 관련이 있다고 생각했을 것입니다.
Alfred Xiao

@AlfredXiao는 동의했습니다. 이것은 저를 놀라게 한 것이기도했지만 말이되는 것 같습니다.
Eugene

1

내가 이해하는대로 "허가"는 스레드가 "파킹 해제"될 수 있는지 여부를 나타내는 객체 일뿐입니다. 그리고 이것은 스레드 자체에 의해 확인됩니다 (또는 스레드를 파킹하려고 할 때 JRE에서 확인합니다). "소비 된"것, 허가가 사라지고 스레드가 비활성화되지 않았 음을 이해합니다.

멀티 스레딩에 대해 조금 더 배워야한다고 생각합니다. "허용"이라는 개체가있는 디스펜서라고 생각하면됩니다. 당신은 쓰레드에게 파킹을 지시하고 쓰레드는 디스펜서를 확인하고, "허가"가 있으면 쓰레드가 그것을 가져다가 떠납니다 (파크없이). 디스펜서에 "허가"가 없으면 "허가"를 사용할 수있을 때까지 스레드가 고정됩니다 (그리고 디스펜서에 "허가"를 넣을 수 있습니다.unpark .

CPU / 메모리 사용량은 OS ​​등에 따라 다르다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.