자바 스레드wait와 notify 상세 분석

3109 단어 javawaitnotify
wait()와 notify()는 Object 클래스에 직접 예속됩니다. 즉, 모든 대상이 이 방법을 가지고 있습니다.처음에는 신기해 보였지만 실제로는 자연스러웠다. 이 방법이 막힐 때 점용하는 자물쇠를 방출해야 하기 때문이다. 자물쇠는 모든 대상이 가지고 있기 때문에 임의의 대상의wait() 방법을 사용하면 라인이 막히고 그 대상의 자물쇠가 방출된다.임의의 대상을 호출하는 notify () 방법은 이 대상의wait () 방법을 호출하여 막힌 라인에서 무작위로 선택한 막힘을 해제합니다. (단, 자물쇠를 얻은 후에야 실행할 수 있습니다.)
그 다음에wait()와 notify()는 어느 위치에서든 호출할 수 있지만 이 방법은 반드시synchronized 방법이나 블록에서 호출해야 한다. 이유도 간단하고synchronized 방법이나 블록의 현재 라인에서만 자물쇠를 차지해야 자물쇠가 방출될 수 있다.같은 이치로 이 방법을 호출하는 대상의 자물쇠는 반드시 현재 라인에 있어야 자물쇠가 방출될 수 있다.따라서 방법 호출은 이러한synchronized 방법이나 블록에 설치해야 한다. 이 방법이나 블록의 잠금 대상은 바로 이런 방법을 호출하는 대상이다.이 조건을 충족시키지 못하면 프로그램은 컴파일할 수 있지만 실행할 때 Illegal MonitorState Exception 이상이 발생합니다.
wait()와 notify() 방법의 상기 특성은 synchronized 방법이나 블록과 자주 사용하도록 결정한다. 그것들을 운영체제의 프로세스 간 통신기와 비교하면 그들의 유사성을 발견할 수 있다. synchronized 방법이나 블록은 운영체제의 원어와 유사한 기능을 제공하고 그들의 실행은 다선정 메커니즘의 방해를 받지 않는다.이 상대방의 법칙은 블록과wakeup 원어에 해당한다.그것들의 결합으로 우리는 운영체제의 일련의 정교한 프로세스 간 통신을 실현하는 알고리즘(예를 들어 신호량 알고리즘)을 실현할 수 있고 각종 복잡한 스레드 간 통신 문제를 해결하는 데 사용할 수 있다.
 
wait () 및 notify () 방법에 대해 마지막으로 두 가지를 설명합니다.
첫째: notify () 방법을 호출하여 막힌 라인을 해제하는 것은 이 대상의wait () 방법을 호출하여 막힌 라인에서 무작위로 선택한 것입니다. 우리는 어떤 라인이 선택될지 예측할 수 없기 때문에 프로그래밍할 때 이런 불확실성으로 인해 문제가 발생하지 않도록 각별히 조심해야 합니다.
둘째: notify () 를 제외하고 notify All () 방법도 유사한 역할을 할 수 있다. 유일한 차이점은 notify All () 방법을 사용하면 이 대상의wait () 방법을 호출하여 막힌 모든 라인을 한꺼번에 모두 막는다는 것이다.물론 자물쇠를 얻은 라인만 실행 가능한 상태로 들어갈 수 있다.
관련wait 및 notify 사용 데모:

/**
 * <pre>
 *  10 , 100 , 10 ,
 *  100 , 50 
 * </pre>
 * @author ketqi
 */
 public class WaitNotifyDemo {
   public static void main(String[] args) {
 
     final Business business = new Business();
     new Thread(new Runnable() {
       @Override
       public void run() {
         for (int i = 1; i <= 50; i++) {
           business.sub(i);
         }
 
       }
     }).start();
 
     for (int i = 1; i <= 50; i++) {
       business.main(i);
     }
   }
 }
 
 class Business {
   private boolean isMainThread = true;
 
   public synchronized void sub(int i) {
     while (!isMainThread) {
       try {
         this.wait();
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
     for (int j = 1; j <= 10; j++) {
       System.out.println("sub thread sequence of " + j + ",loop of " + i);
    }
     isMainThread = false;
     this.notify();
   }
 
  public synchronized void main(int i) {
     while (isMainThread) {
       try {
        this.wait();
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
     for (int j = 1; j <= 100; j++) {
       System.out.println("main thread sequence of " + j + ",loop of " + i);
     }
     isMainThread = true;
     this.notify();
   }
 }
이상은 본문의 전체 내용입니다. 여러분이 좋아하시기 바랍니다.

좋은 웹페이지 즐겨찾기