문제

어떤 사람이기 때문입니다 wait()sleep() 스레드에서?

내 이해 wait()-ing 스레드가 아직도 실행 모드로 사용하여 CPU 사이클이나 sleep()-ing 을 소비하지 않습니다 CPU 사이클이 올바른지?

왜 우리는 모두 wait()sleep():어떻게 자신의 구현을 변화 낮은 수준에서?

도움이 되었습니까?

해결책

wait 다른 스레드 호출에 의해 "깨어날 수 있습니다" notify 기다리는 모니터에서 sleep 할 수 없습니다. 또한 a wait (그리고 notify) 블록에서 발생해야합니다 synchronized 모니터 객체에서 sleep 하지 않습니다:

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

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

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

(같은 mon 객체) 및 첫 번째 스레드 (모니터에서 대기하는 유일한 스레드라고 가정)가 깨어납니다.

당신은 또한 전화 할 수 있습니다 notifyAll 둘 이상의 스레드가 모니터에서 기다리고 있으면 깨어납니다. 그들 모두. 그러나 스레드 중 하나만 모니터를 잡을 수 있습니다 ( wait a synchronized 블록) 그리고 계속해서 - 다른 사람들은 모니터의 잠금을 얻을 수있을 때까지 차단됩니다.

또 다른 요점은 당신이 전화한다는 것입니다 wait ~에 Object 그 자체 (즉, 객체의 모니터를 기다리는 동안) sleep ~에 Thread.

또 다른 요점은 당신이 얻을 수 있다는 것입니다 가짜 깨어 난 ~에서 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 ()를 호출 할 때까지 다른 TimesLice를주지 마십시오.” 와 같은 sleep(), OS는 누군가가 전화하지 않으면 작업을 예약하려고 시도하지 않습니다. notify() (또는 몇 가지 다른 웨이크 업 시나리오 중 하나가 발생합니다).

스레드는 또한 IO 차단을 수행 할 때 나머지 타임 슬라이스를 잃고 몇 가지 다른 상황에서도 잃습니다. 스레드가 전체 타임 슬라이스를 통해 작동하면 OS는 마치 마치 마치 마치 강제로 제어됩니다. yield() 다른 프로세스가 실행될 수 있도록 호출되었습니다.

당신은 거의 필요하지 않습니다 yield(), 그러나 논리적 인 작업 경계가있는 컴퓨팅이 많은 앱이있는 경우 yield() ~할 것 같다 시스템 응답 성을 향상시킵니다 (시간을 희생하여 - 컨텍스트 스위치, OS와 백로조차도 무료가 아닙니다). 항상 그렇듯이 관심있는 목표를 측정하고 테스트하십시오.

여기에는 많은 답이 있지만 언급 한 의미 론적 차이를 찾을 수 없었습니다.

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

sleep() 이전과 마찬가지로 스레드를 잠들게 보냅니다. 컨텍스트를 포장하고 사전 정의 된 시간 동안 실행을 중지합니다. 따라서 적절한 시간 전에 깨어나려면 스레드 참조를 알아야합니다. 이것은 다중 스레드 환경에서 일반적인 상황이 아닙니다. 주로 시간 동기화 (예 : 정확히 3.5 초 안에 깨어남) 및/또는 하드 코딩 된 공정성 (잠시 잠을 자고 다른 스레드가 작동하도록하는 데 사용됩니다).

wait(), 반대로, 스레드 (또는 메시지) 동기화 메커니즘이있어 저장된 참조 (또는 관리)가없는 스레드에 알릴 수 있습니다. 게시 패턴으로 생각할 수 있습니다.wait == 구독 및 notify() == 게시). 기본적으로 notify ()를 사용하면 메시지를 보내고 있습니다 (전혀받지 못하고 일반적으로 신경 쓰지 않을 수도 있습니다).

요약하면, 당신은 일반적으로 사용합니다 sleep() 시간 신속화를 위해 wait() 멀티 스레드-동기화 용.

그것들은 기본 OS에서 동일한 방식으로 구현 될 수 있거나 전혀 구현 될 수 있거나 전혀 구현 될 수 있습니다 (이전 버전의 Java에는 실제 멀티 스레딩이 없었기 때문에 일부 작은 VM도 그렇게하지 않을 것입니다). Java가 VM에서 실행되는 것을 잊지 마십시오. 따라서 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() 어디서나 호출 될 수 있습니다. 구체적인 요구 사항이 없습니다.

ref : 대기와 수면의 차이

대기 및 수면 방법을 호출하기위한 코드 스 니펫

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

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

thread transition to different thread states

어떤 차이가 있는 핵심 노트 내가 결론 후에는 작업에 기다리고 수면,먼저 살펴보를 사용하여 샘 wait()및(수):

Example1:용 ()및 sleep():

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 체
    • 잠():에 스레드를 실행한 작업을 얻는 맥주(는 클래스 메소드를 그렇게 영향을 미치에서 현재 실행 스레드)
  2. :
    • wait():면 동기화된 다중 스레드세 동일한 개체(HandObject)(할 때 필요 간의 통신에 이상 하나의 스레드(thread 실행 코딩,스레드를 실행 얻 맥주)스에서 동일한 개체 HandObject)
    • 잠():기하는 경우에는 조건을 계속 실행(기에 맥주 가능)
  3. 보 잠금:
    • wait():잠금을 해제에 대한 다른 객체를 실행하(HandObject 은 무료입니다,당신이 할 수 있는 다른 일)
    • 잠():유지에 대한 잠금에서 이상 t 번(또는지 인터럽트)(여전히 내 작업이 완료되지 않을,나를 계속 보유 잠금 기다리고 몇 가지 조건이 계속)
  4. 모닝콜 조건:
    • wait():까지 전화를 알리(),notifyAll()에서는 개체
    • 잠():까지도 시간이 만료되거나 전화 인터럽트
  5. 마지막 포인트 할 때 사용estani 나타냅니다:

당신은 일반적으로 사용하(수)시간 동기화 및 wait()한 멀티 스레드 동기화합니다.

저를 수정하시기 바랍니다면 내가 잘못입니다.

Wait ()와 sleep ()의 차이

  • 근본적인 차이점은 그 것입니다 wait() 출신입니다 Object 그리고 sleep() 정적 방법입니다 Thread.

  • 주요 차이점은 wait() 잠금을 방출합니다 sleep() 기다리는 동안 잠금 장치를 해제하지 않습니다.

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

  • wait() 내부 동기화에서 호출해야합니다. 그렇지 않으면 우리는 IllegalMonitorStateException, 동안 sleep() 어디서나 호출 할 수 있습니다.

  • 다시 스레드를 시작합니다 wait(), 당신은 전화해야합니다 notify() 또는 notifyAll(). 에 관해서 sleep(), 지정된 시간 간격 후에 스레드가 시작됩니다.

유사성

  • 둘 다 현재 스레드를 안으로 만듭니다 실행할 수 없습니다 상태.
  • 둘 다 토종의 행동 양식.

이 두 가지 방법 모두 완전히 다른 사용을 갖기 때문에 이것은 매우 간단한 질문입니다.

주요 차이점은 수면이 대기 중에 잠금 또는 모니터를 해제하지 않는 동안 잠금 또는 모니터를 방출하기를 기다리는 것입니다. 대기는 수면을 사용하는 동안 스레드 간 커뮤니케이션에 사용됩니다.

이것은 단지 명확하고 기본적인 설명이었습니다. 그 이상을 원한다면 계속 읽으십시오.

경우 wait() 메소드 스레드는 대기 상태로 들어가고 우리가 호출 할 때까지 자동으로 돌아 오지 않습니다. notify() 방법 (또는 notifyAll() 대기 상태에 스레드가 하나 더 있고 해당 스레드를 모두 깨우고 싶다면). 그리고 액세스하려면 동기화 또는 객체 잠금 또는 클래스 잠금 장치가 필요합니다. wait() 또는 notify() 또는 notifyAll() 행동 양식. 그리고 한 가지 더 wait() 스레드가 대기 상태로 이동하면 해당 스레드를 깨우려면 다른 스레드가 필요하기 때문에 메소드는 스레드 간 통신에 사용됩니다.

그러나 sleep() 이것은 프로세스를 몇 초 동안 또는 원하는 시간 동안 유지하는 데 사용되는 방법입니다. 당신은 아무것도 자극 할 필요가 없기 때문입니다 notify() 또는 notifyAll() 해당 스레드를 되 찾는 메소드. 또는 해당 스레드를 다시 호출하기 위해 다른 스레드가 필요하지 않습니다. 사용자의 턴 후 게임에서 몇 초 후에 무언가가 발생하기를 원한다면 사용자가 컴퓨터가 재생 될 때까지 기다리기를 원합니다. sleep() 방법.

인터뷰에서 자주 묻는 한 가지 더 중요한 차이점 : sleep() 속한다 Thread 수업 및 wait() 속한다 Object 수업.

이것들은 모든 차이점입니다 sleep() 그리고 wait().

그리고 두 방법 사이에는 유사성이 있습니다. 둘 다 확인 된 진술이므로 이러한 방법에 액세스하려면 캐치 또는 던지기가 필요합니다.

이것이 당신을 도울 수 있기를 바랍니다.

원천 : http://www.jguru.com/faq/view.jsp?eid=47127

Thread.sleep() 현재 스레드를 다음으로 보냅니다 "실행할 수 없음" 일정 시간 동안 상태. 스레드는 Aquired가있는 모니터를 유지합니다. 즉, 스레드가 현재 동기화 된 블록 또는 메소드에있는 경우 다른 스레드 가이 블록 또는 메소드를 입력 할 수 없습니다. 다른 스레드가 호출되는 경우 t.interrupt() 수면 실이 깨어납니다.

수면은 정적 방법이므로 항상 현재 실 (수면 방법을 실행하는 스레드)에 영향을 미칩니다. 일반적인 실수는 전화하는 것입니다 t.sleep() 여기서 t는 다른 스레드입니다. 그럼에도 불구하고, 그것은 t 스레드가 아니라 잠을자는 현재 실입니다.

t.suspend() 더 이상 사용되지 않습니다. 그것을 사용하면 현재 스레드 이외의 스레드를 중단 할 수 있습니다. 일시 중단 된 스레드는 모든 모니터를 유지 하며이 상태는 중단되지 않기 때문에 교착 상태가 발생하기 쉽습니다.

object.wait() 현재 스레드를 다음으로 보냅니다 "실행할 수 없음" 상태, 좋아요 sleep(), 그러나 비틀기로. 대기는 실이 아닌 물체에 호출됩니다. 우리는이 개체를 "잠금 객체"라고 부릅니다. 전에 lock.wait() 현재 스레드는 잠금 객체에서 동기화해야합니다. wait()그런 다음이 잠금 장치를 출시하고 잠금 장치와 관련된 "대기 목록"에 스레드를 추가합니다. 나중에 다른 스레드는 동일한 잠금 객체에서 동기화하고 호출 할 수 있습니다. lock.notify(). 이것은 원래 대기실을 깨우고 있습니다. 원래, wait()/notify() 처럼 sleep()/interrupt(), 활성 스레드 만 수면 스레드에 대한 직접적인 포인터가 필요하지 않고 공유 잠금 객체에만 필요합니다.

대기와 수면은 두 가지 다른 것입니다.

  • ~ 안에 sleep() 스레드는 지정된 지속 시간 동안 작동을 중지합니다.
  • ~ 안에 wait() 대기중인 물체에 일반적으로 다른 스레드에 의해 알림이 통지 될 때까지 스레드가 작동이 중지됩니다.

sleep 방법입니다 Thread, wait 방법입니다 Object, 그래서 wait/notify Java에서 공유 데이터를 동기화하는 기술입니다 (사용 감시 장치), 하지만 sleep 스스로를 일시 중지하는 간단한 스레드 방법입니다.

잠() 몇 초 동안 프로세스를 유지하는 데 사용되는 메소드 또는 원하는 시간이지만 Wait () 메소드의 경우 스레드가 대기 상태로 이동하여 Notify () 또는 notifyall ()을 호출 할 때까지 자동으로 돌아 오지 않습니다. .

그만큼 큰 차이 그게 다 기다리다() 수면 ()이 대기 중에 잠금 또는 모니터를 풀지 않는 동안 잠금 또는 모니터를 출시합니다. 대기는 수면이 일반적으로 일시 중지를 도입하는 데 사용되는 동안 스레드 간 통신에 사용됩니다.

Thread.sleep () 현재 스레드를 어느 시간 동안 "실행할 수없는"상태로 보냅니다. 스레드는 획득 한 모니터를 유지합니다. 즉, 스레드가 현재 동기화 된 블록 또는 메소드에있는 경우 다른 스레드 가이 블록 또는 메소드를 입력 할 수없는 경우. 다른 스레드가 t.interrupt () 호출되면 수면 스레드가 깨어납니다. 수면은 정적 방법이므로 항상 현재 실 (수면 방법을 실행하는 스레드)에 영향을 미칩니다. 일반적인 실수는 t.sleep ()를 호출하는 것입니다. 여기서 t는 다른 스레드입니다. 그럼에도 불구하고, 그것은 t 스레드가 아니라 잠을자는 현재 실입니다.

Object.Wait () 현재 스레드를 Sleep ()와 같이 "런닝 할 수없는"상태로 보냅니다. 대기는 실이 아닌 물체에 호출됩니다. 우리는이 개체를“잠금 객체”라고 부릅니다. lock.wait ()가 호출되기 전에 현재 스레드는 잠금 객체에서 동기화해야합니다. 대기 () 그런 다음이 잠금 장치를 출시하고 스레드를 잠금과 관련된 "대기 목록"에 추가합니다. 나중에 다른 스레드는 동일한 잠금 객체에서 동기화하고 Lock.notify ()를 호출 할 수 있습니다. 이것은 원래 대기실을 깨우고 있습니다. 기본적으로 대기 ()/notify ()는 sleep ()/interrupt ()와 같으며 활성 스레드 만 수면 스레드에 대한 직접적인 포인터가 필요하지 않고 공유 잠금 객체에만 필요합니다.

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

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

위의 모든 지점을 분류하십시오.

Call on:

  • 기다리다(): 물건을 호출하십시오. 현재 스레드는 잠금 객체에서 동기화해야합니다.
  • 잠(): 스레드를 호출하십시오. 항상 실행 중입니다.

Synchronized:

  • 기다리다(): 동기화 된 다중 스레드가 동일한 객체를 하나씩 액세스 할 때.
  • 잠(): 동기화 된 여러 스레드가 수면 스레드에서 수면을 기다립니다.

Hold lock:

  • 기다리다(): 다른 개체에 대한 잠금 장치를 실행할 수있는 기회가 있습니다.
  • 잠(): 시간 초과를 지정하거나 누군가가 방해하는 경우 적어도 t 시간 동안 잠금을 유지하십시오.

Wake-up condition:

  • 기다리다(): 호출 notify (), 객체에서 notifyall ()까지
  • 잠(): 적어도 시간이 지나면 인터럽트가 만료되거나 호출됩니다.

Usage:

  • 잠(): 시간 동기화 및;
  • 기다리다(): 멀티 스레드-동기화 용.

ref :차이 sleep 그리고 wait

wait 그리고 sleep 방법은 매우 다릅니다.

  • sleep "깨어"할 방법이없고,
  • 반면 wait 대기 기간 동안 다른 스레드 호출로 "깨우기"방법이 있습니다. notify 또는 notifyAll.

그것에 대해 생각해보십시오. 그 이름은 그 점에서 혼란 스럽습니다. 하지만 sleep 표준 이름이며 wait 같다 WaitForSingleObject 또는 WaitForMultipleObjects Win API에서.

간단히 말해서, 잠에서는 다른 스레드가 당신을 호출 할 때까지 기다리는 반면, 수면은 특정 시간 동안 "다음 문장을 실행하지"않는다.

또한 수면은 스레드 클래스에서 정적 메소드이며 스레드에서 작동하는 반면 Waite ()는 객체 클래스에 있고 객체를 호출합니다.

또 다른 요점, 당신이 객체를 기다릴 때, 스레드는 객체를 동기화 한 다음 기다립니다. :)

이 게시물에서 : http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-java/

대기 () 메소드.

1) Wait () 메소드를 호출하는 스레드는 보유한 잠금 장치를 방출합니다.

2) 다른 스레드가 동일한 잠금 장치에서 notify () 또는 notifyall () 메소드를 호출 한 후 스레드가 잠금을 회복합니다.

3) 대기 () 메소드는 동기화 된 블록 내에서 호출되어야합니다.

4) 대기 () 메소드는 항상 개체에서 호출됩니다.

5) notify () 또는 notifyall () 메소드를 호출하여 다른 스레드가 대기 스레드를 깨울 수 있습니다.

6) Wait () 메소드를 호출하려면 스레드에 객체 잠금이 있어야합니다.

수면 () 방법

1) sleep () 메소드를 호출하는 스레드는 보유한 잠금 장치를 해제하지 않습니다.

2) Sleep () 방법은 동기화 된 블록 내부 또는 외부에서 호출 할 수 있습니다.

3) 수면 () 방법은 항상 스레드에서 호출됩니다.

4) 다른 실로는 수면 실을 깨울 수 없습니다. 그렇게하면 스레드가 중단 예고를 던집니다.

5) sleep () 메소드를 호출하려면 스레드에 객체 잠금이 필요하지 않아도됩니다.

  1. wait() 방법입니다 Object 수업.
    sleep() 방법입니다 Thread 수업.

  2. sleep() 스레드가 이동할 수 있습니다 sleep x 밀리 초의 상태.
    실이 수면 상태로 들어가면 it doesn’t release the lock.

  3. wait() 스레드가 잠금을 해제 할 수 있습니다 goes to suspended state.
    이 스레드는 a notify() 또는 notifAll() 동일한 객체에 대한 메소드가 호출됩니다.

수면/인터럽트와 대기/알림의 잠재적 인 큰 차이는

필요하지 않은 경우 예외를 생성하는 것은 비효율적입니다. 높은 속도로 서로 통신하는 스레드가 있다면, CPU의 총 낭비 인 인터럽트를 항상 호출하는 경우 많은 예외를 생성 할 것입니다.

당신이 맞습니다 - sleep ()는 해당 스레드가 "수면"을 유발하고 CPU가 꺼져서 다른 스레드 (그렇지 않으면 컨텍스트 스위칭이라고도 함)를 처리 할 때 CPU가 현재 스레드를 처리한다고 생각합니다.

우리는 다른 사람들이 CPU를 사용하지 않는 동안 사용하는 것이 합리적으로 보일 수 있지만 실제로는 컨텍스트 전환에 대한 오버 헤드가 있습니다. 수면의 시간에 따라 CPU 사이클에서 더 비쌀 수 있습니다. 스레드를 전환하려면 스레드가 몇ms에 대해 아무것도하지 않도록하는 것입니다.

또한 수면은 컨텍스트 스위치를 강요합니다.

또한 - 일반적으로 컨텍스트 전환을 제어 할 수 없습니다. 대기 중에 OS 5 월 (및 더 긴 대기 시간)은 다른 스레드를 처리하도록 선택합니다.

이 방법은 다른 것들에 사용됩니다.

Thread.sleep(5000);   // Wait until the time has passed.

Object.wait();        // Wait until some other thread tells me to wake up.

Thread.sleep (n) ~할 수 있다 중단되지만 객체. wait () ~ 해야 하다 알림을 받으십시오. 대기 할 최대 시간을 지정할 수 있습니다. Object.wait(5000) 따라서 사용할 수 있습니다 wait ,에, sleep 그러나 당신은 자물쇠를 귀찮게해야합니다.

수면/대기 중에 CPU를 사용하지 않습니다.

이 방법은 유사한 구조물을 사용하지만 동일한 방식으로는 기본 코드를 사용하여 구현됩니다.

자신을 찾으십시오 : 기본 방법의 소스 코드를 사용할 수 있습니까? 파일 /src/share/vm/prims/jvm.cpp 시작점입니다 ...

여기에서 대기 ()는 다른 스레드로 통지 할 때까지 대기 상태에있을 것입니다.

대기 () 및 수면 () 차이?

Thread.sleep () 작업이 완료되면 모든 사람에게 잠금을 해제합니다. 그 자물쇠가 누구에게도 해제되지 않을 때까지.

  Sleep() take the key, its never release the key to anyone, when its work completed then only its release then only take the key waiting stage threads.

Object.wait ()가 대기 중단 단계에 올라 가면 키를 릴리스하고 매개 변수를 기준으로 몇 초 동안 대기합니다.

예를 들어:

당신은 당신의 오른손에 커피를 가져 가고, 같은 손의 다른 사람을 데려 갈 수 있습니다. 언제 내려 놓을 것인지, 다른 물체를 동일한 유형 만 가져갑니다. 또한. 이것은 수면 () 당신이 일하지 않은 수면 시간입니다. 당신은 잠을 자고 있습니다 .. 여기서도 마찬가지입니다.

기다리다(). 당신이 내려 놓고 기다리는 동안 다른 것을 의미 할 때, 그것은 기다립니다.

당신은 연주 영화 또는 당신의 시스템에서 당신의 시스템에서 당신이 한 번에 둘 이상을 연주 할 수없는 플레이어와 동일합니다.

wait 자물쇠를 출시합니다 sleep 그렇지 않습니다. 대기 상태의 실은 곧 깨어날 수 있습니다. notify 또는 notifyAll 호출됩니다. 그러나 sleep 스레드는 잠금 장치를 유지하며 수면 시간이 끝나면 자격이 있습니다.

sleep() 메소드는 현재 스레드가 지정된 시간 동안 실행 상태에서 블록 상태로 이동합니다. 현재 스레드에 모든 객체의 잠금이있는 경우 계속 유지하는 경우 다른 스레드가 해당 클래스 객체에서 동기화 된 메소드를 실행할 수 없습니다.

wait() 메소드는 현재 스레드가 지정된 시간 또는 알림까지 블록 상태로 이동하게하지만이 경우 스레드는 객체의 잠금을 방출합니다 (이는 다른 스레드가 호출 객체의 동기화 된 메소드를 실행할 수 있음을 의미합니다.

내 생각에,주요 차이점을 모두 메커니즘은 잠/인터럽트가 가장 기본적인 방법으로 처리하는 쓰레드 반면 기다릴/알리고 추출을 목적으로 하는 실 inter-communication 쉽습니다. 이 의미는 잠/인터럽트 아무것도 할 수 있지만,이는 특정 작업이 어려워 않습니다.

왜 기다릴/알리는 더 적당합니까?여기에 몇 가지 개인 고려 사항:

  1. 용에 집중. 그것은 조정의 통신 사이의 그룹 스레드와 공유되는 하나의 객체입니다.이 작업을 간소화하고 많습니다.

  2. 그것을 적용합니다. 기 때문에 그것을 만드는 프로그래머 랩 호출을 기다리에게 알려주에서 동기화됩니다.

  3. 그것은 독립적인 스레드의 원본 및 번호입니다. 이 방법을 더 추가할 수 있습니다 스레드가 임의로 편집하지 않고 다른 스레드 또는 트랙을 유지하의 기존하는 것들입니다.사용한 경우 수면/중단,당신이 먼저 해야하는지에 대한 참조 자 스레드한 다음 그들을 방해 하나씩 있습니다.

예를 들어서 실제 생활에 좋은 이것을 설명하기 위해 고전적인 레스토랑하는 방법은 인력을 사용하여 통신하는 그 중:웨이터를 떠나 고객이 요구하는 중앙 위치에서(코르크보드,테이블,etc.), 벨,그리고 노동자가 부엌에서 온 그러한 요청합니다.한 번 있다는 것이 어떤 과정을 준비,부엌 인원에 벨을 눌러 다시는 웨이터가 알고 있습니다.

수면에 대한 예는 잠금을 해제하지 않고 대기하지 않습니다

여기에는 두 가지 수업이 있습니다.

  1. 기본 : 주요 방법과 두 개의 스레드가 포함되어 있습니다.
  2. 하나씩 일어나는 것 : 이것은 GetInstance ()와 GetInstance (부울 등간)가있는 두 가지 정적 메소드가있는 싱글 톤 클래스입니다.

    public class Main {
    
    private static Singleton singletonA = null;
    private static Singleton singletonB = null;
    
    public static void main(String[] args) throws InterruptedException {
    
    Thread threadA = new Thread() {
        @Override
        public void run() {
    
            singletonA = Singleton.getInstance(true);
    
        }
    };
    
    Thread threadB = new Thread() {
        @Override
        public void run() {
            singletonB = Singleton.getInstance();
    
            while (singletonA == null) {
                System.out.println("SingletonA still null");
            }
    
            if (singletonA == singletonB) {
                System.out.println("Both singleton are same");
            } else {
                System.out.println("Both singleton are not same");
            }
    
        }
    };
    
    threadA.start();
    threadB.start();
    
     }
    }
    

그리고

public class Singleton {

    private static Singleton _instance;

    public static Singleton getInstance() {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null)
                _instance = new Singleton();
        }
    }
    return _instance;

}

public static Singleton getInstance(boolean isWait) {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null) {
                if (isWait) {
                    try {
                        // Singleton.class.wait(500);//Using wait
                        Thread.sleep(500);// Using Sleep
                        System.out.println("_instance :"
                                + String.valueOf(_instance));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                _instance = new Singleton();
            }
        }
    }
    return _instance;

 }
}

이제이 예제를 실행하십시오. 출력 아래가 표시됩니다.

_instance :null
Both singleton are same

여기에서 Threada와 Threadb에 의해 생성 된 싱글 톤 인스턴스는 동일합니다. 그것은 Threadb가 릴리스 될 때까지 외부에서 기다리고 있음을 의미합니다.

이제 thread.sleep (500)를 댓글을 달아서 Singleton.java를 변경하십시오. 방법 및 무책임한 Singleton.class.wait (500); . 여기에서 Singleton.class.wait (500) 때문에; Method Threada는 모든 획득 잠금 장치를 릴리스하고 "비 런 가능"상태로 이동하면 Threadb는 동기화 된 블록으로 입력하기 위해 변경됩니다.

이제 다시 실행하십시오 :

SingletonA still null
SingletonA still null
SingletonA still null
_instance :com.omt.sleepwait.Singleton@10c042ab
SingletonA still null
SingletonA still null
SingletonA still null
Both singleton are not same

여기에서 Threada와 Threadb에 의해 생성 된 싱글 톤 인스턴스는 Threadb가 동기화 된 블록에서 입력하기 위해 변경 되었기 때문에 동일하지 않으며 500 밀리 초 후 Threada는 마지막 위치에서 시작하여 싱글 톤 객체를 하나 더 만들었습니다.

동기화 된 블록에서 호출해야합니다. wait() 메소드는 항상 동기화 된 블록에서 호출됩니다 wait() 메소드는 호출되는 객체 앞에 객체 모니터를 잠그려고해야합니다. 하지만 sleep() 방법은 외부 동기화 된 블록에서 호출 될 수 있습니다 sleep() 메소드에는 객체 모니터가 필요하지 않습니다.

불법 모니터 스테이트 exception : 만약에 wait() 메소드는 객체 잠금을 얻지 않고 호출됩니다 IllegalMonitorStateException 런타임에 던져졌지만 sleep() 방법은 그러한 예외를 절대 던지지 않습니다.

어떤 클래스에 속합니다 : wait() 방법은 다음에 속합니다 java.lang.Object 수업이지만 sleep() 방법은 다음에 속합니다 java.lang.Thread 수업.

객체 또는 스레드에서 호출 : wait() 메소드는 개체에서 호출되지만 sleep() 메소드는 객체가 아닌 스레드에서 호출됩니다.

스레드 상태 : 언제 wait() 메소드는 오브젝트에서 호출됩니다. notify() 또는 notifyAll() 그 개체에서 메소드가 호출됩니다. 그리고 나중에 스레드 스케줄러는 스레드가 실행 가능한에서 실행 상태로가는 스레드를 스케줄링합니다. 언제 sleep() 스레드에서 호출됩니다. 실행에서 대기 상태로 이동하여 수면 시간이 올라갈 때 달리기 상태로 돌아갈 수 있습니다.

동기화 된 블록에서 호출 될 때 : 언제 wait() 메소드는 객체 잠금을 잎이라고합니다. 하지만 sleep() 메소드 동기화 된 블록 또는 메소드 스레드에서 호출 된 경우 객체 잠금을 남기지 않습니다.

이상 참조

Oracle Documentation Page에서 기다리다() 의 방법 Object:

public final void wait()
  1. 다른 스레드가 다른 스레드가 notify() 방법 또는 notifyAll() 이 개체에 대한 방법. 다시 말해,이 메소드는 단순히 전화를 수행하는 것처럼 정확하게 동작합니다. wait(0).
  2. 현재 스레드는이 객체의 모니터를 소유해야합니다. 스레드는이 모니터의 소유권을 공개하고 다른 스레드 가이 개체의 모니터에서 대기하는 스레드를 알 때까지 기다립니다.
  3. 인터럽트와 가짜 웨이크 업이 가능합니다
  4. 이 방법은이 개체의 모니터의 소유자 인 스레드에 의해서만 호출되어야합니다.

이 방법은 던졌습니다

  1. IllegalMonitorStateException - 현재 스레드가 객체 모니터의 소유자가 아닌 경우.

  2. InterruptedException - 스레드가 현재 스레드가 알림을 기다리는 동안 전류 스레드를 방해 한 경우. 이 예외가 발생하면 현재 스레드의 중단 상태가 지워집니다.

Oracle Documentation Page에서 잠() 의 방법 Thread 수업:

public static void sleep(long millis)
  1. 시스템 타이머 및 스케줄러의 정밀도와 정확성에 따라 지정된 밀리 초에 대한 현재 실행 스레드가 잠을 자고 (일시적으로 실행을 중단).
  2. 스레드는 모니터의 소유권을 잃지 않습니다.

이 방법은 다음과 같습니다.

  1. IllegalArgumentException - Millis의 값이 음수 인 경우

  2. InterruptedException - 스레드가 현재 스레드를 중단 한 경우. 이 예외가 발생하면 현재 스레드의 중단 상태가 지워집니다.

기타 주요 차이점 :

wait() 정적 메소드와 달리 비 정적 메소드 (인스턴스 메소드)입니다. sleep() (수업 방법).

wait() 동기화 된 방법으로 제공됩니다 sleep() 동기화되지 않은 메소드 내부에서 제공됩니다 wait() 메소드 객체의 잠금을 해제하지만 sleep() 또는 yield() 릴리스를 해제합니다 lock().

타임 아웃 값으로 기다리면 타임 아웃 값이 경과 할 때 깨어날 수 있거나 이전 (또는 중단)을 알리면 시간 초과 값이 경과하거나 중단되는 시간에 잠이 깨어납니다. 대기 () 타임 아웃 값이없는 () 알림 또는 중단 될 때까지 기다릴 것입니다.

  • 방법 wait(1000) 현재 실이 잠을 자게합니다 최대 1 초.
    • 실이 1 초 미만으로 잠을 잘 수 있습니다. notify() 또는 notifyAll() 방법 호출.
  • 전화 sleep(1000) 현재 실이 잠을 자게합니다 정확히 1 초.
    • 또한 수면 스레드는 자원을 잠그지 않습니다. 그러나 대기실이 있습니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top