자바 대기 각성 메커니즘 원리 및 사용
이것 은 심혈 을 기울 인 구덩이 메 우기 노트 입 니 다.자바 를 독학 한 몇 년 동안 새로운 기술 을 계속 배 웠 습 니 다.걸 어 오 면서 자신 이 구 덩이 를 많이 밟 았 다 는 것 을 알 게 되 었 고 채 워 진 구 덩이 는 손 에 꼽 을 수 있 습 니 다.갑자기 가끔 은 정말 몇 년 의 업무 경험 이 문제 가 아니 라 10 년 동안 일 해도 열심히 공부 하지 않 은 것 이 10 년 의 큰 구덩이 에 불과 하 다 는 것 을 알 게 되 었 다.
다 중 스 레 드 를 처음 접 했 을 때 이 물건 을 기다 리 거나 깨 울 줄 알 았 습 니 다.demo 라 고 쓰 면 다 시 는 보지 못 했 습 니 다.그것 이 도대체 무엇 인지,아니면 어떤 문 제 를 해결 할 수 있 는 지 에 대해 서 는 대부분의 사람들 이 저 와 마찬가지 로 애매모호 할 것 입 니 다.이번에 필 자 는 당신 을 데 리 고 기다 림/깨 우기 체 제 를 이해 하려 고 합 니 다.본 고 를 읽 으 면 다음 과 같은 몇 가 지 를 얻 을 것 입 니 다.
만약 에 오늘 월급 을 주 려 고 한다 면 강 사장 은 좋 은 음식 을 먹 으 러 가 야 한다.전체 식사 절 차 는 다음 과 같은 몇 가지 절차 로 나 눌 수 있다.
 public static void main(String[] args) {
   //       
    AtomicBoolean hasBun = new AtomicBoolean();
    
    //      
    new Thread(() -> {
      try {
        //             
        while (true) {
          if (hasBun.get()) {
            System.out.println("  :           ...");
            Thread.sleep(3000);
          } else {
            System.out.println("  :     ,       ...");
            Thread.sleep(1000);
            System.out.println("  :     ....");
            hasBun.set(true);
          }
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }).start();
    new Thread(() -> {
      System.out.println("  :     ...");
      try {
        //             
        while (!hasBun.get()) {
          System.out.println("  :        ~");
          Thread.sleep(3000);
        }
        System.out.println("  :       ....");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }).start();
  } 
 위의 코드 에 큰 문제 가 존재 한다.바로 사장 이 만두 가 있 는 지 계속 검사 해 야 하고 고객 은 일정 시간 간격 으로 사장 을 보 러 가 야 한다.이것 은 분명 합 리 적 이지 않다.이것 이 바로 전형 적 인 순환 대기 문제 이다.
 
 이런 문제 의 코드 에는 보통 다음 과 같은 모델 이 있다.
  while (     ) {
    Thread.sleep(3000);
  }
  doSomething();둘째,대기/깨 우기 메커니즘
순환 대기 CPU 소모 및 정보 신속 성 문 제 를 해결 하기 위해 자바 에 서 는 대기 각성 체 제 를 제공 합 니 다.쉽게 말 하면 주동 에서 수 동적 으로 바 뀌 고 조건 이 성립 될 때 해당 하 는 스 레 드 를 주동 적 으로 통지 하 는 것 이지 스 레 드 자체 에 문의 하 게 하 는 것 이 아니다.
2.1 기본 개념
대기/깨 우기 메커니즘 은 대기 알림(필 자 는 알림 이 아 닌 깨 우기)이 라 고도 부른다.스 레 드 A 가 대상 O 의 wait()방법 을 호출 하여 대기 상태 에 들 어 갔 고 다른 스 레 드 는 O 의 notify()또는 notify All()방법 을 호출 했다.스 레 드 A 가 통 지 를 받 은 후에 대상 O 의 wait()방법 으로 돌아 와 후속 작업 을 수행 했다.
항소 과정 은 대상 O 를 통 해 스 레 드 A 와 스 레 드 B 간 에 통신 을 하고 스 레 드 에서 대상 O 의 wait()방법 을 호출 한 후 스 레 드 가 오랫동안 차단 상태 에 들 어 갔 으 며 다른 스 레 드 에서 대상 O 가 notify()또는 notify All 방법 을 호출 할 때 해당 하 는 차단 스 레 드 를 깨 웁 니 다.
2.2 기본 API
시스템 에 대한 방법 을 기다 리 거나 깨 울 때 임의의 자바 대상 이 갖 추고 있 습 니 다.이 방법 들 은 모든 자바 대상 의 초 클래스 Object 에 정의 되 어 있 기 때 문 입 니 다.
notify:대상 에서 기다 리 는 스 레 드 를 wait()방법 으로 되 돌려 주 고 되 돌아 오 는 전제 에서 대상 의 자 물 쇠 를 가 져 옵 니 다.
notify All:이 대상 을 기다 리 는 모든 스 레 드 를 알려 줍 니 다.
wait:이 방법 을 사용 하 는 스 레 드 는 차단 대기 상태 에 들 어 갑 니 다.다른 스 레 드 의 알림 을 기다 리 거나 중단 되 어야 돌아 갑 니 다.wait 방법 을 사용 하면 대상 의 자 물 쇠 를 풀 수 있 습 니 다.
wait(long):한 동안 깨 어 나 지 않 으 면 시간 을 초과 하여 자동 으로 돌아 갑 니 다.단 위 는 밀리초 입 니 다.
2.3 대기 각성 메커니즘 으로 순환 대기 최적화
public static void main(String[] args) {
  //       
    AtomicBoolean hasBun = new AtomicBoolean();
    //    
    Object lockObject = new Object();
    //      
    new Thread(() -> {
      try {
        while (true) {
          synchronized (lockObject) {
            if (hasBun.get()) {
              System.out.println("  :     ,       ");
              lockObject.wait(); 
            } else {
              System.out.println("  :     ,       ...");
              Thread.sleep(3000);
              System.out.println("  :     ....");
              hasBun.set(true);
              //        
              lockObject.notifyAll();
            }
          }
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }).start();
    new Thread(() -> {
      System.out.println("  :     ...");
      try {
        synchronized (lockObject) {
          if (!hasBun.get()) {
            System.out.println("  :        ,     cruder      ");
            lockObject.wait(); 
          } else {
            System.out.println("  :       ,      ....");
            hasBun.set(false);
            lockObject.notifyAll();
            System.out.println("  :           ,         ~~");
          }
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }).start();
 } 
 상기 절 차 는 폴 링 검사 의 조작 을 줄 이 고 스 레 드 가 wait()방법 을 호출 한 후에 자 물 쇠 를 방출 하여 CPU 자원 을 소모 하지 않 고 프로그램의 성능 을 향상 시 켰 다.
3.깨 우기 메커니즘 의 기본 패 러 다 임 을 기다린다.
대기,깨 우 는 것 은 스 레 드 간 통신 의 수단 중 하나 로 여러 스 레 드 가 같은 데이터 소스 를 조작 하 는 것 을 조율 하 는 데 사용 된다.실제 응용 에서 순환 대기 문 제 를 최적화 시 키 고 대기 자 와 통지 자 를 대상 으로 다음 과 같은 전형 적 인 범례 를 추출 할 수 있다.
주의해 야 할 것 은 대기 자가 실행 하 는 논리 에서 while 순환 으로 대기 조건 을 판단 해 야 한 다 는 것 입 니 다.notify/notify All 방법 을 실행 할 때 대기 스 레 드 를 wait 방법 에서 되 돌려 주 는 것 이지 임계 구역 에 다시 들 어 가 는 것 이 아 닙 니 다.
/**
 *         
 * 1.       
 * 2.     ,       ,     wait  ,          
 * 3.             
 */
synchronized(  ){
  while(     ){
      .wait()
  }
  doSomething();
}
/**
 * !!         
 * 1.       
 * 2.     
 * 3.   (  )         
 */
synchronized(  ){
      
    .notify();
}4.notify/notifyAll 잠 금 해제 하지 않 음
이 문 제 는 엔지니어 의 절반 이 모 르 고 wait()방법 을 실행 하면 자물쇠 가 자동 으로 풀 려 날 것 이 라 고 믿 습 니 다.그러나 notify()방법 을 실행 한 후 자 물 쇠 는 풀 리 지 않 고 notify()방법 이 있 는 synchronized 코드 블록 을 실행 해 야 풀 립 니 다.이 점 은 매우 중요 하고 많은 엔지니어 들 이 소홀히 하기 쉬 운 부분 이다.
lockObject.notifyAll();
System.out.println("  :           ,         ~~");5.대기,각성 은 먼저 자 물 쇠 를 가 져 와 야 합 니 다.
대기,깨 우기 프로 그래 밍 모드 에서 wait,notify,notify All 방법 은 직접 호출 되 지 않 습 니 다.잠 금 을 가 져 온 임계 구역 에서 실행 해 야 합 니 다.
그리고 같은 자물쇠 에 기다 리 는 스 레 드 만 깨 울 수 있 습 니 다.
스 레 드 가 wait 방법 을 호출 할 때 대기 열 에 가입 합 니 다.notify 를 실행 할 때 대기 열 에 있 는 첫 번 째 대기 스 레 드(대기 시간 이 가장 긴 스 레 드)를 깨 우 고 notify All 을 호출 할 때 대기 스 레 드 에 있 는 모든 대기 스 레 드 를 깨 웁 니 다.
 
 6,sleep 자 물 쇠 를 풀 지 않 고 wait 방출\#
대기 깨 우기 메커니즘 으로 순환 기다 림 을 최적화 하 는 과정 에서 중요 한 특징 은 원래 의 sleep()방법 을 wait()방법 으로 대체 하 는 것 이다.그들의 가장 큰 차이 점 은 wait 방법 은 자 물 쇠 를 방출 하 는 것 이 고 sleep 는 그렇지 않다 는 것 이다.그 밖 에 중요 한 차이 점 이 있다.sleep 는 Thread 의 방법 으로 임 의적 으로 실행 할 수 있다.wait 는 Object 대상 의 방법 으로 synchronized 코드 블록 에서 실행 해 야 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.