etc./StackOverFlow

wait()와 sleep()의 차이점

청렴결백한 만능 재주꾼 2023. 4. 24. 06:48
반응형

질문자 :Geek


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

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

wait()sleep() 이 모두 있는 이유는 무엇입니까? 낮은 수준에서 구현이 어떻게 다른가요?



wait 는 대기 중인 모니터에서 notify 를 호출하는 다른 스레드에 의해 "깨어날" 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(); } }

oxbow_lakes

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

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

Robert Munteanu

이 게시물이 도움이 되었습니다. Thread.sleep() , Thread.yield()Object.wait() 의 차이점을 인간의 관점에서 설명합니다. 인용하려면:

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

sleep(n)"타임슬라이스가 끝났습니다. 최소한 n밀리초 동안 다른 타임슬라이스를 제공하지 마세요."라고 말합니다. OS는 요청된 시간이 지날 때까지 잠자는 스레드를 예약하려고 시도하지 않습니다.

yield()"타임슬라이스는 끝났지만 아직 할 일이 있습니다."라고 말합니다. OS는 즉시 스레드에 또 다른 타임슬라이스를 제공하거나, 다른 스레드를 제공하거나, 생성 스레드가 방금 포기한 CPU를 처리할 수 있습니다.

wait()"타임슬라이스 작업을 마쳤습니다. 누군가가 notify()를 호출할 때까지 다른 타임슬라이스를 제공하지 마십시오.” sleep() notify() 호출하지 않는 한(또는 몇 가지 다른 깨우기 시나리오 중 하나가 발생하지 않는 한) 작업을 예약하려고 시도하지 않습니다.

스레드는 차단 IO를 수행할 때와 몇 가지 다른 상황에서 나머지 타임슬라이스를 잃게 됩니다. 스레드가 전체 타임슬라이스를 통해 작동하면 OS는 yield() 가 호출된 것처럼 강제로 제어하여 다른 프로세스를 실행할 수 있습니다.

yield() 거의 필요하지 않지만 논리적 작업 경계가 있는 컴퓨팅 집약적인 앱이 있는 경우 yield() 삽입하면 시스템 응답성이 향상될 수 있습니다 (시간을 희생하여 컨텍스트 전환, OS 및 그 반대로도 ' 무료). 항상 그렇듯이 관심 있는 목표에 대해 측정하고 테스트합니다.


E-rich

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

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

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

wait() 는 저장된 참조가 없는(또는 관심이 없는) 스레드에 알릴 수 있는 스레드(또는 메시지) 동기화 메커니즘입니다. 발행-구독 패턴으로 생각할 수 있습니다( wait == subscribe 및 notify() == publish). 기본적으로 notify()를 사용하여 메시지를 보내고 있습니다(전혀 수신되지 않을 수도 있고 일반적으로 신경 쓰지 않을 수도 있음).

요약하자면 일반적으로 시간 동기화 sleep() wait() 를 사용합니다.

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


estani

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() 은 어디에서나 호출될 수 있습니다. 특별한 요구 사항은 없습니다.

참조: 대기와 절전의 차이점

wait 및 sleep 메소드를 호출하기 위한 코드 스니펫

 synchronized(monitor){ while(condition == true){ monitor.wait() //releases monitor lock } Thread.sleep(100); //puts current thread on Sleep }

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


roottraveller

wait()와 sleep()의 차이점

  • 근본적인 차이점은 wait() Object 비정적 메서드이고 sleep() Thread 의 정적 메서드라는 것입니다.
  • 주요 차이점은 wait() 는 잠금을 해제하는 반면 sleep() 은 기다리는 동안 잠금을 해제하지 않는다는 것입니다.
  • wait() 는 스레드 간 통신 sleep() 은 일반적으로 실행 일시 중지를 도입하는 데 사용됩니다.
  • wait() 는 내부에서 호출해야 합니다. 그렇지 않으면 IllegalMonitorStateException 이 발생하고 sleep() 은 어디에서나 호출할 수 있습니다.
  • wait() 에서 스레드를 다시 시작하려면 notify() 또는 notifyAll() 무기한 호출 notify() 합니다. sleep(), 의 경우 지정된 시간 간격 후에 스레드가 확실히 시작됩니다.

유사점

  • 둘 다 현재 스레드를 Not Runnable 상태로 만듭니다.
  • 둘 다 기본 메서드입니다.

Premraj

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

예 1 : wait () 및 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 개체를 보유하는 현재 스레드를 호출합니다.
    • sleep(): 스레드 실행 작업 호출 맥주 가져오기(클래스 메서드이므로 현재 실행 중인 스레드에 영향을 미침)
  2. 동기화됨 :
    • wait(): 동기화된 다중 스레드가 동일한 객체(HandObject)에 액세스할 때 (둘 이상의 스레드 간에 통신이 필요한 경우(스레드 실행 코딩, 스레드 실행) 동일한 객체에 대한 액세스 HandObject )
    • sleep(): 계속 실행을 기다리는 조건(맥주 사용 가능)
  3. 잠그기 :
    • wait(): 다른 객체에 대한 잠금 해제 실행 기회가 있음(HandObject는 무료이며 다른 작업을 수행할 수 있음)
    • sleep(): 적어도 t번(또는 인터럽트가 발생할 때까지) 동안 잠금을 유지합니다(내 작업이 아직 완료되지 않았습니다. 계속 잠금을 유지하고 계속하기 위해 몇 가지 조건을 기다리고 있습니다)
  4. 기상 조건 :
    • wait(): 객체에서 notify(), notifyAll()을 호출할 때까지
    • sleep(): 최소한 시간이 만료되거나 호출이 중단될 때까지
  5. 그리고 마지막 요점은 estani 가 다음을 나타낼 때 사용하는 것입니다.

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

내가 틀렸다면 저를 수정하십시오.


NguyenDat

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

주요 차이점은 잠자기가 대기하는 동안 잠금 또는 모니터를 해제하지 않는 동안 잠금 해제를 기다리거나 모니터하는 것입니다. 대기는 스레드 간 통신에 사용되는 반면 절전은 실행 일시 중지를 도입하는 데 사용됩니다.

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

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

그러나 sleep() 경우 몇 초 또는 원하는 시간 동안 프로세스를 유지하는 데 사용되는 메서드입니다. 당신이 자극이 필요하지 않기 때문에 어떤 notify() 또는 notifyAll() 메소드는 스레드 다시 얻을 수 있습니다. 또는 해당 스레드를 다시 호출하기 위해 다른 스레드가 필요하지 않습니다. 게임에서 사용자 턴 후 몇 초 후에 무언가가 일어나기를 원한다면 사용자가 컴퓨터가 재생될 때까지 기다리기를 원할 때 sleep() 메소드를 언급할 수 있습니다.

그리고 인터뷰에서 자주 묻는 또 다른 중요한 차이점은 sleep()Thread 클래스에 wait() Object 클래스에 속한다는 것입니다.

이것이 모두 sleep()wait() 의 차이점입니다.

그리고 두 메서드 사이에는 유사점이 있습니다. 둘 다 검사된 문이므로 이러한 메서드에 액세스하려면 catch 또는 throw를 시도해야 합니다.

이것이 도움이 되기를 바랍니다.


Vikas Gupta

출처 : http://www.jguru.com/faq/view.jsp?EID=47127

Thread.sleep() 은 현재 스레드를 일정 시간 동안 "Not Runnable" 상태로 보냅니다. 스레드는 획득한 모니터를 유지합니다. 즉, 스레드가 현재 동기화된 블록이나 메서드에 있으면 다른 스레드가 이 블록이나 메서드에 들어갈 수 없습니다. 다른 스레드가 t.interrupt() 호출하면 잠자는 스레드를 깨울 것입니다.

sleep은 정적 메서드이므로 항상 현재 스레드(sleep 메서드를 실행하는 스레드)에 영향을 줍니다. 일반적인 실수는 t가 다른 스레드인 t.sleep() 그렇더라도 t 스레드가 아니라 잠자기 상태가 되는 현재 스레드입니다.

t.suspend() 는 더 이상 사용되지 않습니다. 이를 사용하면 현재 스레드가 아닌 다른 스레드를 중지할 수 있습니다. 일시 중단된 스레드는 모든 모니터를 유지하며 이 상태는 인터럽트할 수 없으므로 교착 상태가 발생하기 쉽습니다.

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


om singh

기다림과 잠자는 두 가지 다른 것입니다.

  • sleep() 에서 스레드는 지정된 기간 동안 작동을 멈춥니다.
  • wait() 에서 스레드는 일반적으로 다른 스레드에 의해 대기 중인 개체가 알림을 받을 때까지 작업을 중지합니다.

Itay Maman

sleep Thread 의 메서드이고 wait Object 의 메서드이므로 wait/notify 는 Java에서 공유 데이터를 동기화하는 기술( monitor 사용)이지만 sleep 은 스레드가 스스로 일시 중지하는 간단한 메서드입니다.


pvllnspk

sleep() 은 몇 초 동안 또는 원하는 시간 동안 프로세스를 유지하는 데 사용되는 메서드이지만 wait() 메서드의 경우 스레드가 대기 상태가 되고 notify()를 호출할 때까지 자동으로 돌아오지 않습니다. 모든 알림().

주요 차이점wait() 는 잠금 또는 모니터를 해제하는 반면 sleep()은 기다리는 동안 잠금이나 모니터를 해제하지 않는다는 것입니다. 대기는 스레드 간 통신에 사용되는 반면 슬립은 일반적으로 실행 일시 중지를 도입하는 데 사용됩니다.

Thread.sleep() 은 현재 스레드를 일정 시간 동안 "Not Runnable" 상태로 보냅니다. 스레드는 획득한 모니터를 유지합니다. 즉, 스레드가 현재 동기화된 블록 또는 메서드에 있는 경우 다른 스레드가 이 블록이나 메서드에 들어갈 수 없습니다. 다른 스레드가 t.interrupt()를 호출하면 잠자는 스레드를 깨울 것입니다. sleep은 정적 메서드이므로 항상 현재 스레드(sleep 메서드를 실행하는 스레드)에 영향을 줍니다. 일반적인 실수는 t가 다른 스레드인 t.sleep()을 호출하는 것입니다. 그렇더라도 t 스레드가 아니라 잠자기 상태가 되는 현재 스레드입니다.

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

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

위의 모든 사항을 분류합니다.

Call on:

  • wait(): 객체를 호출합니다. 현재 스레드는 잠금 개체에서 동기화해야 합니다.
  • sleep(): 스레드를 호출합니다. 항상 현재 실행 중인 스레드.

Synchronized:

  • wait(): 동기화된 여러 스레드가 동일한 개체에 하나씩 액세스할 때.
  • sleep(): 동기화될 때 여러 스레드가 잠자는 스레드의 절전 모드를 기다립니다.

Hold lock:

  • wait(): 다른 객체가 실행할 기회를 갖도록 잠금을 해제합니다.
  • sleep(): 타임아웃이 지정되거나 누군가가 인터럽트하면 적어도 t번 동안 잠금을 유지합니다.

Wake-up condition:

  • wait(): 객체에서 notify(), notifyAll()을 호출할 때까지
  • sleep(): 최소한 시간이 만료되거나 interrupt()를 호출할 때까지.

Usage:

  • sleep(): 시간 동기화 및;
  • wait(): 다중 스레드 동기화를 위한 것입니다.

참조: diff sleepwait


Reegan Miranda

간단히 말해서 wait는 다른 스레드가 호출할 때까지 기다리는 반면 sleep은 지정된 시간 동안 "다음 명령문을 실행하지 않음"입니다.

또한 sleep은 Thread 클래스의 정적 메서드이며 스레드에서 작동하는 반면 wait()는 Object 클래스에 있고 개체에서 호출됩니다.

또 다른 점은 일부 개체에서 wait를 호출하면 관련된 스레드가 개체를 동기화한 다음 기다립니다. :)


Ratnesh Maurya

waitsleep 방법은 매우 다릅니다.

  • sleep 에는 "깨어날" 방법이 없습니다.
  • 반면 wait "깨어 업"대기 기간 동안, 다른 스레드의 호출에 의해의 방법이 notify 또는 notifyAll .

생각해 보면 이름이 그런 점에서 혼란스럽습니다. 그러나 sleep 은 표준 이름이고 wait 는 Win API WaitForSingleObject 또는 WaitForMultipleObjects 와 같습니다.


Roee Adler

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

wait() 메서드.

1) wait() 메소드를 호출하는 스레드는 보유하고 있는 잠금을 해제합니다.

2) 다른 스레드가 동일한 잠금에 대해 notify() 또는 notifyAll() 메서드를 호출한 후 스레드가 잠금을 다시 얻습니다.

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

4) wait() 메소드는 항상 객체에 대해 호출됩니다.

5) 대기 중인 스레드는 notify() 또는 notifyAll() 메서드를 호출하여 다른 스레드에서 깨울 수 있습니다.

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

sleep() 메서드

1) sleep() 메서드를 호출하는 스레드는 보유하고 있는 잠금을 해제하지 않습니다.

2) sleep() 메서드는 동기화된 블록 내부 또는 외부에서 호출할 수 있습니다.

3) sleep() 메서드는 항상 스레드에서 호출됩니다.

4) 잠자는 쓰레드는 다른 쓰레드에 의해 깨울 수 없다. 그렇게 하면 스레드가 InterruptedException을 throw합니다.

5) sleep() 메서드를 호출하기 위해 스레드는 객체 잠금을 가질 필요가 없습니다.


user2485429

여기에서 wait()는 다른 스레드가 알릴 때까지 대기 상태에 있지만 sleep()은 시간이 있을 것입니다. 그 후에는 자동으로 Ready 상태로 전환됩니다...


Rakhi Jaligama

  1. wait() Object 클래스의 메소드입니다.
    sleep() Thread 클래스의 메서드입니다.

  2. sleep() 은 스레드가 x 밀리초 동안 sleep
    스레드가 절전 상태 it doesn't release the lock .

  3. wait() 는 스레드가 잠금을 해제하도록 허용 goes to suspended state 됩니다.
    이 스레드는 동일한 객체에 대해 notify() 또는 notifAll() 메서드가 호출될 때 활성화됩니다.


VeKe

절전/인터럽트와 대기/알림의 잠재적인 큰 차이점 중 하나는

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


Mark

맞습니다 - Sleep()은 해당 스레드를 "잠자기" 상태로 만들고 CPU가 꺼지고 다른 스레드(컨텍스트 전환이라고도 함)를 처리하는 반면 Wait는 CPU가 현재 스레드를 계속 처리한다고 생각합니다.

CPU를 사용하지 않는 동안 다른 사람들이 CPU를 사용하도록 하는 것이 합리적으로 보일 수 있지만 실제로 컨텍스트 전환에 대한 오버헤드가 있기 때문에 두 가지가 모두 있습니다. 절전 시간에 따라 CPU 주기에서 더 비쌀 수 있습니다. 스레드를 전환하는 것은 단순히 스레드가 몇 ms 동안 아무 것도 하지 않도록 하는 것입니다.

또한 절전 모드는 컨텍스트 전환을 강제 실행합니다.

또한 - 일반적으로 컨텍스트 전환을 제어하는 것은 불가능합니다 - Wait 동안 OS는 다른 스레드를 처리하도록 선택할 수 있습니다.


Justin

방법은 다양한 용도로 사용됩니다.

 Thread.sleep(5000); // Wait until the time has passed. Object.wait(); // Wait until some other thread tells me to wake up.

Thread.sleep를 (N)을 중단 할 있지만, 지정된 Object.wait ()를 통보해야합니다. 최대 대기 시간을 지정할 수 있습니다. Object.wait(5000) wait to, er, sleep 을 사용할 수 있지만 잠금을 처리해야 합니다.

두 방법 모두 절전/대기 중에 CPU를 사용하지 않습니다.

메소드는 유사한 구조를 사용하지만 동일한 방식이 아닌 네이티브 코드를 사용하여 구현됩니다.

스스로 찾아보세요: 네이티브 메서드의 소스 코드를 사용할 수 있습니까? /src/share/vm/prims/jvm.cpp 파일이 시작점입니다...


KarlP

Wait() 및 sleep() 차이점?

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() 대기 단계로 이동하면 키가 해제되고 매개변수에 따라 몇 초 동안 대기합니다.

예를 들어:

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

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

당신은 영화 또는 플레이어와 동일한 시스템의 모든 것을 재생합니다. 한 번에 둘 이상을 재생할 수 없습니다. 바로 여기입니다. 닫고 다른 사람을 선택할 때 영화 또는 노래는 대기라고 불리는 동안 의미합니다.


VISALIG

wait 는 잠금을 해제하고 sleep 은 해제하지 않습니다. 대기 상태에있는 스레드가 빨리으로 깨어 난 자격이 notify 또는 notifyAll 호출된다. 그러나 sleep 의 경우 스레드는 잠금을 유지하며 휴면 시간이 종료된 후에만 적격합니다.


shikjohari

sleep() 메서드는 현재 스레드가 지정된 시간 동안 실행 상태에서 블록 상태로 이동하도록 합니다. 현재 스레드에 객체에 대한 잠금이 있으면 계속 보유하고 있습니다. 즉, 다른 스레드는 해당 클래스 객체에서 동기화된 메서드를 실행할 수 없습니다.

wait() 메서드는 현재 스레드가 지정된 시간 동안 또는 알림이 표시될 때까지 블록 상태가 되도록 하지만 이 경우 스레드는 객체의 잠금을 해제합니다(즉, 다른 스레드가 호출하는 객체의 동기화된 메서드를 실행할 수 있음을 의미합니다.


User10001

제 생각에는 두 메커니즘의 주요 차이점은 절전/인터럽트가 스레드를 처리하는 가장 기본적인 방법인 반면 대기/알림은 스레드 간 통신을 보다 쉽게 수행하기 위한 추상화라는 것입니다. 즉, 절전/인터럽트는 무엇이든 할 수 있지만 이 특정 작업은 수행하기가 더 어렵습니다.

왜 wait/notify가 더 적합합니까? 다음은 개인적인 고려 사항입니다.

  1. 중앙 집중화를 시행합니다. 단일 공유 객체로 스레드 그룹 간의 통신을 조정할 수 있습니다. 이것은 작업을 많이 단순화합니다.

  2. 동기화를 시행합니다. 프로그래머가 동기화된 블록에서 대기/알림 호출을 래핑하게 하기 때문입니다.

  3. 스레드 원점 및 번호와 무관합니다. 이 접근 방식을 사용하면 다른 스레드를 편집하거나 기존 스레드를 추적하지 않고 임의로 더 많은 스레드를 추가할 수 있습니다. 절전/인터럽트를 사용한 경우 먼저 절전 스레드에 대한 참조를 유지한 다음 수동으로 하나씩 인터럽트해야 합니다.

이것을 설명하기에 좋은 실생활의 예는 고전적인 레스토랑과 직원들이 그들 사이에서 의사 소통하기 위해 사용하는 방법입니다. 웨이터는 고객 요청을 중앙 위치(코르크 보드, 테이블 등)에 두고 벨을 누르면 주방에서 일하는 직원들이 그런 요청을 받으러 온다. 코스가 준비되면 주방 직원이 다시 벨을 눌러 웨이터가 인식하고 고객에게 가져갈 수 있도록 합니다.


negora

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

여기에 두 가지 클래스가 있습니다.

  1. Main : 메인 메소드와 두 개의 스레드를 포함합니다.
  2. Singleton : 두 개의 정적 메서드 getInstance() 및 getInstance(boolean isWait)가 있는 싱글톤 클래스입니다.

     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에 의해 생성된 Singleton 인스턴스는 동일합니다. 이는 threadB가 threadA가 잠금을 해제할 때까지 외부에서 기다리고 있음을 의미합니다.

이제 Thread.sleep(500)에 주석을 달아 Singleton.java를 변경하십시오. 메서드 및 주석 해제 Singleton.class.wait(500); . Singleton.class.wait(500); 메소드 threadA는 모든 획득 잠금을 해제하고 "Non Runnable" 상태로 이동하고, 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에 의해 생성된 Singleton 인스턴스는 동기화된 블록에 입력할 변경 사항이 threadB에 있고 500밀리초 후에 threadA가 마지막 위치에서 시작하여 하나 이상의 Singleton 개체를 생성했기 때문에 동일하지 않습니다.


Dhiral Pandya

동기화된 블록에서 호출해야 합니다. wait() 메서드는 항상 동기화된 블록에서 호출됩니다. 즉, wait() 메서드는 호출되는 개체보다 먼저 개체 모니터를 잠글 필요가 있습니다. 그러나 sleep() 메서드는 외부 동기화 블록에서 호출할 수 있습니다. 즉 sleep() 메서드는 개체 모니터가 필요하지 않습니다.

IllegalMonitorStateException : 객체 잠금을 획득하지 않고 wait() 메서드가 호출되면 런타임에 IllegalMonitorStateException sleep() 메서드는 이러한 예외를 throw하지 않습니다.

어느 클래스에 속해 있는지 wait() java.lang.Object 클래스에 sleep() 메서드는 java.lang.Thread 클래스에 속한다.

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

스레드 상태 : wait() 메소드가 객체에서 호출, 만들었 었지 객체의 모니터는 대기 상태로 실행 이동 및 실행 가능한 전용 상태로 돌아갈 수 있다는 스레드 notify() 또는 notifyAll() 메소드는 해당 객체에 호출된다. 그리고 나중의 스레드 스케줄러는 해당 스레드가 실행 가능한 상태에서 실행 중인 상태로 이동하도록 예약합니다. sleep() 이 호출되면 실행에서 대기 상태로 전환되고 절전 시간이 다 되면 실행 가능한 상태로 돌아갈 수 있습니다.

동기화된 블록에서 호출wait() 메서드가 호출될 때 스레드는 개체 잠금을 해제합니다. 그러나 동기화된 블록 또는 메서드 스레드에서 호출될 때 sleep()

더 많은 참조를 위해


AVI

Object wait() 메소드에 대한 Oracle 문서 페이지에서 :

 public final void wait()
  1. 다른 스레드가 이 객체에 대한 notifyAll() 메서드 또는 notifyAll() 메서드를 호출할 때까지 현재 스레드가 대기 notify() wait(0) 호출을 수행하는 것처럼 정확하게 동작합니다.
  2. 현재 스레드는 이 개체의 모니터를 소유해야 합니다. 스레드는 이 모니터의 소유권을 해제하고 다른 스레드가 이 개체의 모니터에서 대기 중인 스레드가 깨어나도록 알릴 때까지 기다립니다.
  3. 인터럽트 및 가짜 깨우기가 가능합니다.
  4. 이 메서드는 이 개체의 모니터 소유자인 스레드에서만 호출해야 합니다.

이 메서드는

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

  2. InterruptedException - 현재 스레드가 알림을 기다리는 동안 또는 그 이전에 현재 스레드를 인터럽트한 스레드가 있는 경우. 이 예외가 발생하면 현재 스레드의 중단된 상태가 지워집니다.

Thread 클래스 의 sleep() 메서드에 대한 Oracle 문서 페이지에서:

 public static void sleep(long millis)
  1. 시스템 타이머와 스케줄러의 정밀도와 정확성에 따라 현재 실행 중인 스레드가 지정된 밀리초 동안 휴면(일시적으로 실행 중지)되도록 합니다.
  2. 스레드는 모니터의 소유권을 잃지 않습니다.

이 메서드는 다음을 던집니다.

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

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

기타 주요 차이점:

wait() sleep() (클래스 메서드)과 달리 비정적 메서드(인스턴스 메서드)입니다.


Ravindra babu

wait() 는 동기화된 메서드 내부에 제공되는 반면 sleep() 은 비동기화된 메서드 내부에 제공됩니다. wait() 메서드가 객체에 대한 잠금을 해제하지만 sleep() 또는 yield() lock() 해제하기 때문입니다.


Aravind Mano

  • wait(1000) 메서드는 현재 스레드를 최대 1초 동안 잠자기 상태로 만듭니다.
    • notify() 또는 notifyAll() 메서드 호출을 수신하는 경우 1초 미만으로 잠자기 상태가 될 수 있습니다.
  • sleep(1000) 호출 하면 현재 스레드가 정확히 1초 동안 절전 모드로 전환됩니다.
    • 또한 잠자는 스레드는 리소스를 잠그지 않습니다 . 그러나 대기 스레드는 수행합니다.

Rupesh

사실, 이 모든 것이 Java 문서에 명확하게 설명되어 있습니다(그러나 나는 답변을 읽은 후에야 깨달았습니다).

http://docs.oracle.com/javase/8/docs/api/index.html :

wait() - 현재 스레드가 이 개체의 모니터를 소유해야 합니다. 스레드는 이 모니터의 소유권을 해제하고 다른 스레드가 이 개체의 모니터에서 대기 중인 스레드에게 notify 메소드 또는 notifyAll 메소드 호출을 통해 깨우라고 알릴 때까지 기다립니다. 그런 다음 스레드는 모니터의 소유권을 다시 얻고 실행을 재개할 수 있을 때까지 기다립니다.

sleep() - 시스템 타이머와 스케줄러의 정밀도와 정확성에 따라 현재 실행 중인 스레드가 지정된 밀리초 동안 휴면(일시적으로 실행 중지)되도록 합니다. 스레드는 모니터의 소유권을 잃지 않습니다.


TT_

출처 : http:www.stackoverflow.com/questions/1036754/difference-between-wait-and-sleep

반응형