[java] wait ()와 sleep ()의 차이점

스레드 wait()sleep()스레드 의 차이점은 무엇입니까 ?

wait()-ing 스레드가 여전히 실행 모드이고 CPU 사이클을 사용하지만 sleep()-ing이 CPU 사이클을 올바르게 소비하지 않는다는 것을 이해하고 있습니까?

왜 우리는 다음 과 같은 두 가지를 모두 가지고 있습니까?wait()sleep()



답변

A waitnotify대기중인 모니터를 호출하는 다른 스레드에 의해 “깨어날”수 있습니다 sleep. 또한 wait(및 notify)는 synchronized모니터 객체 의 블록 에서 발생해야 하지만 다음과 같은 sleep것은 아닙니다.

Object mon = ...;
synchronized (mon) {
    mon.wait();
} 

이 시점에서 현재 실행중인 스레드는 모니터를 대기 하고 해제합니다 . 다른 스레드가 할 수 있습니다

synchronized (mon) { mon.notify(); }

(동일한 mon객체에서) 첫 번째 스레드 (모니터에서 대기중인 스레드 만 가정)가 깨어납니다.

notifyAll모니터에서 둘 이상의 스레드가 대기중인 경우 에도 호출 할 수 있습니다. 이렇게하면 모든 스레드가 깨어 납니다 . 그러나, 스레드 중 하나만합니다 (이 기억 모니터를 잡을 수있을 것 waitsynchronized다른 사람이 그 때 모니터의 잠금을 획득 할 수있을 때까지 차단됩니다 – 블록)와 계속.

또 다른 점은 전화 할 것입니다 waitObject당신이 전화를하는 반면 (즉, 당신이 객체의 모니터에서 대기) 자체 sleepThread.

또 다른 요점은 가짜 웨이크 업 을 얻을 수 있다는 것 입니다 wait(즉, 대기중인 스레드가 명백한 이유없이 재개됩니다). 다음과 같이 항상 wait어떤 상태에서 회전 해야 합니다.

synchronized {
    while (!condition) { mon.wait(); }
}


답변

아직 언급되지 않은 한 가지 주요 차이점은 스레드를자는 동안 스레드가 보유한 잠금을 해제 하지 않고 대기하는 동안 wait()호출 되는 객체의 잠금을 해제한다는 것 입니다.

synchronized(LOCK) {
    Thread.sleep(1000); // LOCK is held
}


synchronized(LOCK) {
    LOCK.wait(); // LOCK is not held
}


답변

나는 발견 이 게시물이 도움이. 그것은 차이두고 Thread.sleep(), Thread.yield()그리고 Object.wait()인간의 측면에서입니다. 인용 :

결국 모든 프로세스와 스레드에 타임 슬라이스를 전달하는 OS 스케줄러로 넘어갑니다.

sleep(n)말한다 “나는 내 타임 슬라이스로 끝났어요, 그리고 나에게 최소한 n 밀리 초 또 다른 하나를 포기하지 마십시오.” OS는 요청 된 시간이 지날 때까지 슬리핑 스레드를 예약하지 않습니다.

yield()말한다 “나는 내 타임 슬라이스로 끝났어요,하지만 난 아직 할 일이 있습니다.” OS는 스레드에 즉시 다른 타임 슬라이스를 제공하거나 다른 스레드를 제공하거나 CPU가 처리 한 스레드가 방금 포기한 프로세스를 처리 할 수 ​​있습니다.

wait()라고 내 타임 슬라이스로 끝났어요. ” 누군가 notify ()를 호출 할 때까지 다른 타임 슬라이스를주지 마십시오.” 와 마찬가지로 sleep()OS는 누군가가 전화하지 않으면 notify()(또는 다른 웨이크 업 시나리오 중 하나가 발생 하지 않는 한) 작업 예약을 시도하지도 않습니다 .

스레드는 IO 차단 및 기타 상황에서 나머지 타임 슬라이스를 잃습니다. 스레드가 전체 시간 조각을 통해 작동하는 경우 OS는 마치 마치 yield()호출 된 것처럼 대략적으로 제어 하여 다른 프로세스를 실행할 수 있습니다.

거의 필요하지 않지만 yield()논리적 인 작업 경계를 가진 계산량이 많은 앱을 사용하는 경우 시스템 응답 속도를 향상시킬 yield() 수 있습니다 . 항상 그렇듯이 관심있는 목표를 측정하고 테스트하십시오.


답변

여기에 많은 대답이 있지만 언급 된 의미 론적 차이점을 찾을 수 없습니다.

스레드 자체에 관한 것이 아닙니다. 서로 다른 사용 사례를 지원하므로 두 가지 방법이 모두 필요합니다.

sleep()스레드를 이전과 같이 휴면 상태로 보내고 컨텍스트를 압축하고 미리 정의 된 시간 동안 실행을 중지합니다. 따라서 마감 시간 전에 깨우려면 스레드 참조를 알아야합니다. 다중 스레드 환경에서는 일반적인 상황이 아닙니다. 주로 시간 동기화 (예 : 정확히 3.5 초 깨우기) 및 / 또는 하드 코딩 된 공정성 (잠시 동안 잠자기 및 다른 스레드가 작동하도록 함)에 사용됩니다.

wait()반대로, 스레드 (또는 메시지) 동기화 메커니즘은 저장된 참조 (또는 관리)가없는 스레드를 통지 할 수있게합니다. 이것을 publish-subscribe 패턴 ( wait== subscribe 및 notify()== publish) 으로 생각할 수 있습니다 . 기본적으로 notify ()를 사용하면 메시지를 보내고 있습니다 (아직 전혀받지 못하고 일반적으로 상관하지 않습니다).

요약하면 일반적으로 sleep()시간 동기화 및 wait()다중 스레드 동기화에 사용합니다.

그것들은 기본 OS에서 동일한 방식으로 구현되거나 전혀 구현되지 않을 수 있습니다 (이전 버전의 Java에는 실제 멀티 스레딩이 없었기 때문에 일부 작은 VM도 그렇게하지 않습니다). VM에서 Java 실행을 잊지 마십시오. 코드는 VM / OS / HW에 따라 다르게 변환됩니다.


답변

여기에 wait()sleep()메소드 사이의 중요한 차이점이 거의 없습니다 .
추신 : 또한 링크를 클릭하여 라이브러리 코드를 확인하십시오 (내부 작업, 이해를 돕기 위해 조금만 놀아보십시오).

기다림()

  1. wait() 메소드는 잠금을 해제합니다.
  2. wait()Object클래스 의 방법입니다 .
  3. wait() 비 정적 방법입니다- public final void wait() throws InterruptedException { //...}
  4. wait()notify()또는 notifyAll()방법 으로 통지해야합니다 .
  5. wait() 잘못된 경보를 처리하려면 루프에서 메소드를 호출해야합니다.

  6. wait() 동기화 된 컨텍스트에서 메소드를 호출해야합니다 (예 : 동기화 된 메소드 또는 블록). 그렇지 않으면 IllegalMonitorStateException

자다()

  1. sleep() 메소드는 잠금을 해제하지 않습니다.
  2. sleep()java.lang.Thread클래스 의 방법입니다 .
  3. sleep() 정적 방법입니다- public static void sleep(long millis, int nanos) throws InterruptedException { //... }
  4. 지정된 시간이 지나면 sleep() 완료됩니다.
  5. sleep()루프에서 호출하지 않는 것이 좋습니다 (즉, 아래 코드 참조 ).
  6. sleep()어디서나 호출 될 수 있습니다. 특정 요구 사항이 없습니다.

참고 : 대기와 수면의 차이점

대기 및 절전 메소드 호출을위한 코드 스 니펫

synchronized(monitor){
    while(condition == true){
        monitor.wait()  //releases monitor lock
    }

    Thread.sleep(100); //puts current thread on Sleep    
}

다른 스레드 상태로 스레드 전환


답변

대기 및 수면 작업을 마친 후 결론을 내리는 몇 가지 차이점이 있습니다. 먼저 wait () 및 sleep ()을 사용하여 샘플을 살펴보십시오.

예 1 : 대기 () 및 절전 () 사용

synchronized(HandObject) {
    while(isHandFree() == false) {
        /* Hand is still busy on happy coding or something else, please wait */
        HandObject.wait();
    }
}

/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
    /* Beer is still coming, not available, Hand still hold glass to get beer,
       don't release hand to perform other task */
    Thread.sleep(5000);
}

/* Enjoy my beer now ^^ */
drinkBeers();

/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
    HandObject.notifyAll();
}

몇 가지 주요 사항을 명확하게 설명하십시오.

  1. 전화 :
    • wait () : HandObject 객체를 보유하는 현재 스레드 호출
    • sleep () : 스레드 실행 호출이 맥주를 얻습니다 (클래스 메소드이므로 현재 실행중인 스레드에 영향을 미침)
  2. 동기화 :
    • wait () : 동기화 된 다중 스레드 액세스 동일한 객체 (HandObject) 일 때 (동일한 객체에 대한 둘 이상의 스레드 간 통신이 필요한 경우 (스레드 실행 코딩, 스레드 실행 맥주) 액세스)
    • sleep () : 대기 조건이 계속 실행될 때 (대기 맥주 사용 가능)
  3. 잠금 유지 :
    • wait () : 다른 객체에 대한 잠금 해제 (HandObject는 무료, 다른 작업을 수행 할 수 있음)
    • sleep () : 적어도 t 번 (또는 중단 될 때까지) 잠금을 유지하십시오 (내 작업이 아직 완료되지 않았습니다.
  4. 웨이크 업 조건 :
    • wait () : 객체에서 notify (), notifyAll ()을 호출 할 때까지
    • sleep () : 적어도 시간이 지날 때까지 또는 호출 중단
  5. 그리고 마지막 점입니다 때 사용 으로 estani을 나타냅니다

일반적으로 시간 동기화에는 sleep ()을 사용하고 다중 스레드 동기화에는 wait ()를 사용합니다.

내가 틀렸다면 정정 해주세요.


답변

wait ()와 sleep ()의 차이점

  • 기본적인 차이는 즉 wait()내지 Objectsleep()의 고정 방법 Thread.

  • 가장 큰 차이점은 wait()잠금을 sleep()해제하고 대기하는 동안 잠금을 해제하지 않는다는 것입니다.

  • wait()스레드 간 통신 sleep()에 사용되는 반면 일반적으로 실행 일시 중지를 도입하는 데 사용됩니다.

  • wait()내부 동기화 호출 그렇지 않으면 우리가 얻을해야 IllegalMonitorStateException하지만, sleep() 어디서든 호출 할 수 있습니다.

  • 에서 스레드를 다시 시작하려면 또는 wait()을 호출해야합니다 . 에 관해서는 스레드 지정된 시간 간격 후에 시작됩니다.notify()notifyAll()sleep(),

유사점

  • 둘 다 현재 스레드를 실행 불가능 상태로 만듭니다.
  • 둘 다 기본 방법입니다.