Java 프로그램 동시 Wait-Notify 메커니즘 상세 정보

3014 단어 JavaWait-Notify
Wait-Notify 장면
일반적인 Wait-Notify 장면은 일반적으로 다음 두 가지 내용과 관련이 있습니다.
1. 상태 변수(State Variable)
라인이wait를 필요로 할 때, 항상 일부 조건이 만족을 얻지 못해서 발생한다.예를 들어 대기열에 데이터를 채우면 대기열 요소가 가득 차면wait가 실행을 멈춰야 합니다.대기열 요소가 비어 있을 때, 자신의 실행을 계속합니다.
2. 조건 단언(Condition Predicate)
라인이wait에 들어갔는지 아니면 notify에서 깨어났을 때 계속 실행되었는지 확인하려면 대부분 상태 조건이 충족되었는지 테스트해야 한다.예를 들어 대기열에 원소를 추가하면 대기열이 가득 차서 현재 라인을 막습니다. 다른 라인이 대기열에서 원소를 가져오면 대기하는 라인에'대열에 남은 공간이 있으니 원소를 추가할 수 있습니다'라고 알려 줍니다.이 때 원소 추가를 기다리는 프로세스가 깨워집니다. 그리고 현재 대기열에 남은 공간이 있는지 판단하고, 남은 공간이 있으면 원소를 추가하고, 없으면 다음 깨우기를 계속 막습니다.
3. 조건 대기열(Condition Queue)
모든 대상은 내장된 조건 대기열을 가지고 있으며, 하나의 라인이 이 대상의 자물쇠에서wait 함수를 호출할 때, 이 라인을 이 대상의 조건 대기열에 추가합니다.
주의하다
wait와 notify는 자바 동기화 메커니즘의 중요한 구성 부분이다.synchronized 키워드와 결합하여 사용하면 많은 우수한 동기화 모델을 구축할 수 있다. 예를 들어 생산자-소비자 모델이다.그러나wait(), notify(), notifyAll() 함수를 사용할 때 다음과 같은 몇 가지를 주의해야 한다.
wait (), notify (), notify All () 방법은Thread 클래스가 아니라 Object 기본 클래스에 속합니다. 즉, 모든 대상에wait (), notify (), notify All () 기능이 있습니다.모든 대상에 자물쇠가 있기 때문에 자물쇠는 모든 대상의 기초이기 때문에 자물쇠를 조작하는 방법도 가장 기초적이다.
obj의wait (), notify () 방법을 호출하기 전에 obj 자물쇠를 받아야 합니다. 즉synchronized (obj) {...}코드 세그먼트 내.
obj를 호출합니다.wait () 후, 스레드 A는 obj의 자물쇠를 방출합니다. 그렇지 않으면 스레드 B는 obj 자물쇠를 얻을 수 없고, synchronized (obj) {...}코드 세그먼트에서 스레드 A를 깨웁니다.
obj로 삼다.wait () 방법이 되돌아온 후, 스레드 A는 obj 자물쇠를 다시 받아야 계속 실행할 수 있습니다.
만약 라인 A1, A2, A3가 모두 obj에 있다면.wait (), 라인 B가 obj를 호출합니다.notify () 는 스레드 A1, A2, A3 중 하나만 깨울 수 있습니다.
만약 스레드 B가 obj를 호출한다면.notifyAll () 은 기다린 스레드 A1, A2, A3를 모두 깨울 수 있지만, 기다린 스레드는 obj를 계속 실행해야 합니다.wait () 의 다음 문장은obj 자물쇠를 획득해야 합니다.따라서 라인 A1, A2, A3는 자물쇠를 계속 실행할 수 있는 기회가 하나밖에 없다. 예를 들어 A1, 나머지는 A1이 obj 자물쇠를 풀어야만 계속 실행할 수 있다.
스레드 B에서 obj를 호출합니다.notify () 또는obj.notify All () 때 라인 B가 obj 자물쇠를 가지고 있기 때문에 라인 A1, A2, A3는 깨어났지만 obj 자물쇠를 얻을 수 없습니다.스레드 B가synchronized 코드 블록을 종료하고obj 자물쇠를 푼 후에야 스레드 A1, A2, A3 중 하나가 대상 자물쇠를 얻고 계속 실행할 수 있습니다.
예제 코드
라인의wait 작업의 전형적인 코드 구조는 다음과 같다.

  public void test() throws InterruptedException { 
    synchronized(obj) { 
      while (! contidition) { 
        obj.wait(); 
      } 
    } 
  } 

왜 obj.wait () 작업은 반드시 순환 중입니까?다음과 같은 주요 원인은 다음과 같습니다.
1. 하나의 대상 자물쇠는 여러 개의 상태 변수를 보호하는 데 사용될 수 있습니다. 모두wait-notify 작업이 필요할 때,wait를while 순환에 넣지 않으면 문제가 발생합니다.예를 들어 어떤 대상이 obj를 잠그면 두 가지 상태 변수 a와 b를 보호한다. a의 조건 단언이 성립되지 않을 때wait 조작이 발생하고 b의 조건 단언이 성립되지 않을 때wait 조작이 발생하며 두 라인이obj에 대응하는 조건 대기열에 추가된다.현재 상태 변수 a의 어떤 조작이 발생하면obj에서 notifyAll 조작을 호출하면obj에 대응하는 조건 대기열의 모든 라인이 깨어난다. 이전에 a의 한 개 또는 몇 개의 라인을 기다려서 a의 조건 단언이 성립될 수 있지만 b에 대한 조건 단언은 성립되지 않을 것이다. 이때 b를 기다리는 라인도 깨어나기 때문에 b의 조건 단언이 충족되었는지 순환적으로 판단해야 한다. 만약 만족하지 않는다면,계속 기다릴게요.
2. 여러 개의 루트wait의 동일한 상태의 조건 단언.예를 들어 대기열에 원소를 추가하는 장면은 현재 대기열이 꽉 차서 여러 라인이 안에 원소를 추가하려고 하기 때문에wait가 되었다.이때 다른 스레드가 대기열에서 하나의 요소를 꺼내서 notifyAll 동작을 호출하여 모든 스레드를 깨웠지만, 하나의 스레드만 대기열에 하나의 요소를 추가할 수 있고, 다른 것은 기다려야 합니다.
3. 거짓으로 깨운다.알림, 중단, 시간 초과 없이 라인이 자동으로 깨어났다.이런 상황은 실천에서 드물지만 순환 기다림을 통해 이를 막을 수 있다.

좋은 웹페이지 즐겨찾기