스레드 wait()
와 sleep()
스레드 의 차이점은 무엇입니까 ?
wait()
-ing 스레드가 여전히 실행 모드이고 CPU 사이클을 사용하지만 sleep()
-ing이 CPU 사이클을 올바르게 소비하지 않는다는 것을 이해하고 있습니까?
왜 우리는 다음 과 같은 두 가지를 모두 가지고 있습니까?wait()
sleep()
스레드 wait()
와 sleep()
스레드 의 차이점은 무엇입니까 ?
wait()
-ing 스레드가 여전히 실행 모드이고 CPU 사이클을 사용하지만 sleep()
-ing이 CPU 사이클을 올바르게 소비하지 않는다는 것을 이해하고 있습니까?
왜 우리는 다음 과 같은 두 가지를 모두 가지고 있습니까?wait()
sleep()
답변:
A wait
는 notify
대기중인 모니터를 호출하는 다른 스레드에 의해 "깨어날"수 있습니다 sleep
. 또한 wait
(및 notify
)는 synchronized
모니터 객체 의 블록 에서 발생해야 하지만 다음과 같은 sleep
것은 아닙니다.
Object mon = ...;
synchronized (mon) {
mon.wait();
}
이 시점에서 현재 실행중인 스레드는 모니터를 대기 하고 해제합니다 . 다른 스레드가 할 수 있습니다
synchronized (mon) { mon.notify(); }
(동일한 mon
객체에서) 첫 번째 스레드 (모니터에서 대기중인 스레드 만 가정)가 깨어납니다.
notifyAll
모니터에서 둘 이상의 스레드가 대기중인 경우 에도 호출 할 수 있습니다. 이렇게하면 모든 스레드가 깨어 납니다 . 그러나, 스레드 중 하나만합니다 (이 기억 모니터를 잡을 수있을 것 wait
에 synchronized
다른 사람이 그 때 모니터의 잠금을 획득 할 수있을 때까지 차단됩니다 - 블록)와 계속.
또 다른 점은 전화 할 것입니다 wait
에 Object
당신이 전화를하는 반면 (즉, 당신이 객체의 모니터에서 대기) 자체 sleep
에 Thread
.
또 다른 요점은 가짜 웨이크 업 을 얻을 수 있다는 것 입니다 wait
(즉, 대기중인 스레드가 명백한 이유없이 재개됩니다). 다음과 같이 항상 wait
어떤 상태에서 회전 해야 합니다.
synchronized {
while (!condition) { mon.wait(); }
}
wait
/ notify
는 일반적으로 다른 스레드가 작업을 수행하거나 특정 조건이 충족 될 때까지 대기하는 데 사용됩니다.
아직 언급되지 않은 한 가지 주요 차이점은 스레드를자는 동안 스레드가 보유한 잠금을 해제 하지 않고 대기하는 동안 wait()
호출 되는 객체의 잠금을 해제한다는 것 입니다.
synchronized(LOCK) {
Thread.sleep(1000); // LOCK is held
}
synchronized(LOCK) {
LOCK.wait(); // LOCK is not held
}
sleep
은 Java 잠금 을 보유하고 있다고 오도하게 주장 하지만 그렇지 않습니다. 공정한 비교를 위해, 우리는 비교 것 synchronized(OUTER_LOCK){ Thread.sleep(1000); }
와 함께 synchronized(OUTER_LOCK){ synchronized(LOCK){LOCK.wait();} }
우리는 모두 지침은 공개하지 않는 것을 볼 수 있습니다 OUTER_LOCK
. 차이점이 있다면 sleep
명시 적으로 Java 잠금을 사용 하지 않는다고 말할 수 는 있지만, "구현 수준이 어떻게 다른가 ?" 인용을 해제하십시오.
wait()
는 코드 예제에서 호출 된 가장 안쪽 잠금 상태와 관련이 있으며 wait()
해제 할 수는 LOCK
없습니다 OUTER_LOCK
. 어쨌든 Java 모니터가 설계된 방식입니다. 공정한 비교는 synchronized(OUTER_LOCK){ synchronized(LOCK) { Thread.sleep(1000); } }
and synchronized(OUTER_LOCK){ synchronized(LOCK) { LOCK.wait(); } }
입니다. 이 사건에서 sleep()
동안 모두 잠금을 개최합니다 wait()
발표 할 예정이다 LOCK
하지만 여전히 유지OUTER_LOCK
나는 발견 이 게시물이 도움이. 그것은 차이두고 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(n)
현재 실행중인 스레드가 잠금 모니터를 자발적으로 포기한다는 것을 암시 적으로 말하지만 사실 이 아닙니다 . 스레드의 javadoc 에서 인용 : "스레드는 모니터의 소유권을 잃지 않습니다."
sleep
다른 Java 메소드 호출보다 모니터와 관련하여 특별한 동작 이 없기 때문에 어떤 방식 으로든 상호 작용하거나 수정하지 않습니다. 모니터에 대해 언급하려는 경우 wait
위에서 언급 한 것 외에도 호출 된 오브젝트의 잠금을 일시적으로 포기하도록 지정해야합니다 .
wait(n)
와 비교하는 데 사용 합니다 sleep(n)
. 인수없는 것을 사용하는 것을 비교하는 것은 의미가 없습니다.
여기에 많은 대답이 있지만 언급 된 의미 론적 차이점을 찾을 수 없습니다.
스레드 자체에 관한 것이 아닙니다. 서로 다른 사용 사례를 지원하므로 두 가지 방법이 모두 필요합니다.
sleep()
스레드를 이전과 같이 휴면 상태로 보내고 컨텍스트를 압축하고 미리 정의 된 시간 동안 실행을 중지합니다. 따라서 마감 시간 전에 깨우려면 스레드 참조를 알아야합니다. 다중 스레드 환경에서는 일반적인 상황이 아닙니다. 주로 시간 동기화 (예 : 정확히 3.5 초 깨우기) 및 / 또는 하드 코딩 된 공정성 (잠시 동안 잠자기 및 다른 스레드가 작동하도록 함)에 사용됩니다.
wait()
반대로, 스레드 (또는 메시지) 동기화 메커니즘은 저장된 참조 (또는 관리)가없는 스레드를 통지 할 수있게합니다. 이것을 publish-subscribe 패턴 ( wait
== subscribe 및 notify()
== publish) 으로 생각할 수 있습니다 . 기본적으로 notify ()를 사용하면 메시지를 보내고 있습니다 (아직 전혀받지 못하고 일반적으로 상관하지 않습니다).
요약하면 일반적으로 sleep()
시간 동기화 및 wait()
다중 스레드 동기화에 사용합니다.
그것들은 기본 OS에서 동일한 방식으로 구현되거나 전혀 구현되지 않을 수 있습니다 (이전 버전의 Java에는 실제 멀티 스레딩이 없었기 때문에 일부 작은 VM도 그렇게하지 않습니다). VM에서 Java 실행을 잊지 마십시오. 코드는 VM / OS / HW에 따라 다르게 변환됩니다.
여기에 wait()
와 sleep()
메소드 사이의 중요한 차이점이 거의 없습니다 .
추신 : 또한 링크를 클릭하여 라이브러리 코드를 확인하십시오 (내부 작업, 이해를 돕기 위해 조금만 놀아보십시오).
wait()
메소드는 잠금을 해제합니다. wait()
Object
클래스 의 방법입니다 .wait()
비 정적 방법입니다- public final void wait() throws InterruptedException { //...}
wait()
notify()
또는 notifyAll()
방법 으로 통지해야합니다 .wait()
잘못된 경보를 처리하려면 루프에서 메소드를 호출해야합니다.
wait()
동기화 된 컨텍스트에서 메소드를 호출해야합니다 (예 : 동기화 된 메소드 또는 블록). 그렇지 않으면 IllegalMonitorStateException
sleep()
메소드는 잠금을 해제하지 않습니다.sleep()
java.lang.Thread
클래스 의 방법입니다 .sleep()
정적 방법입니다- public static void sleep(long millis, int nanos) throws InterruptedException { //... }
sleep()
완료됩니다.sleep()
루프에서 호출하지 않는 것이 좋습니다 (즉, 아래 코드 참조 ).sleep()
어디서나 호출 될 수 있습니다. 특정 요구 사항이 없습니다.참고 : 대기와 수면의 차이점
대기 및 절전 메소드 호출을위한 코드 스 니펫
synchronized(monitor){
while(condition == true){
monitor.wait() //releases monitor lock
}
Thread.sleep(100); //puts current thread on Sleep
}
Thread.sleep()
다른 스레드에서 프로세서 시간을 사용할 수있게하는 데 사용됩니다. 휴면 기간은 인터럽트 (즉, JVM)에 의해 종료 될 수 있습니다. 이 stackoverflow.com/questions/4264355/…를
notify()
또는 notifyAll()
있는 Object
클래스 메소드. 따라서 그들은 모든 클래스의 obj를 사용할 수 있습니다 (즉, 여기 Thread
클래스도 있습니다). grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…
대기 및 수면 작업을 마친 후 결론을 내리는 몇 가지 차이점이 있습니다. 먼저 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();
}
몇 가지 주요 사항을 명확하게 설명하십시오.
일반적으로 시간 동기화에는 sleep ()을 사용하고 다중 스레드 동기화에는 wait ()를 사용합니다.
내가 틀렸다면 정정 해주세요.
기본적인 차이는 즉 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()
현재 스레드 를 일정 시간 동안 "실행 불가능" 상태 로 보냅니다 . 스레드는 요청한 모니터를 유지합니다. 즉, 스레드가 현재 동기화 된 블록 또는 메소드에있는 경우 다른 스레드는이 블록 또는 메소드를 입력 할 수 없습니다. 다른 스레드가 호출하는 경우t.interrupt()
하면 잠자는 스레드를 깨 웁니다.sleep은 정적 메소드이므로 항상 현재 스레드 (sleep 메소드를 실행중인 스레드)에 영향을 미칩니다. 일반적인 실수는
t.sleep()
t가 다른 스레드 인 곳 을 호출 하는 것입니다 . 그럼에도 불구하고 t 스레드가 아닌 현재 스레드입니다.
t.suspend()
더 이상 사용되지 않습니다. 사용하면 현재 스레드 이외의 스레드를 중단 할 수 있습니다. 일시 중단 된 스레드는 모든 모니터를 유지하며이 상태는 인터럽트 할 수 없으므로 교착 상태가 발생하기 쉽습니다.
object.wait()
현재 스레드 를와 같은 "Not Runnable" 상태 로 보냅니다sleep()
. 스레드가 아닌 객체에서 대기가 호출됩니다. 이 개체를 "잠금 개체"라고합니다.lock.wait()
호출 되기 전에 현재 스레드는 잠금 오브젝트에서 동기화해야합니다.wait()
그런 다음이 잠금을 해제하고 잠금과 연관된 "대기 목록"에 스레드를 추가합니다. 나중에 다른 스레드가 동일한 잠금 객체에서 동기화하고를 호출 할 수 있습니다lock.notify()
. 원래 대기 스레드를 깨 웁니다. 기본적으로,wait()
/notify()
처럼sleep()
/interrupt()
만 활성 스레드 만 공유 잠금 개체, 잠자는 스레드에 대한 직접적인 포인터를 필요로하지 않는다.
대기와 수면은 서로 다른 두 가지입니다.
sleep()
스레드가 지정된 시간 동안 작동을 멈 춥니 다.wait()
실 물체 존재 기다리는 기능까지 통지 일반적으로 다른 스레드에 의해, 작동하지.sleep
정지 시키려면, 다른 입력에서 입력이 나올 때까지 쓰레드를 멈추려 면 wait
/ 를 사용하십시오 notify
. interrupt
스레드가 스레드의 작업 수행을 중지하고 종료해야한다는 신호를 보내는 방식으로 고안되었습니다. 그것은에 의해 처리됩니다 sleep
, wait
뿐만 아니라 (그리고 당신이 메서드를 호출하여 동일한 동작과 기능을 구현할 수있는 I / O 기능을 차단 Thread.interrupted()
). 성능과 관련하여 기능은 일반적으로 설계된 목표에 맞게 최적화됩니다.
sleep () 은 몇 초 동안 또는 원하는 시간 동안 프로세스를 유지하는 데 사용되는 메소드이지만 wait () 메소드 스레드가 대기 상태가되고 notify ()를 호출 할 때까지 자동으로 돌아 오지 않습니다. notifyAll ().
가장 큰 차이점 은 wait () 가 잠금 또는 모니터를 해제하는 반면 sleep ()은 대기 중 잠금 또는 모니터를 해제하지 않는다는 것입니다. 대기는 스레드 간 통신에 사용되는 반면 절전은 일반적으로 실행 일시 중지를 발생시키는 데 사용됩니다.
Thread.sleep () 은 현재 스레드를 일정 시간 동안 "실행할 수 없음"상태로 보냅니다. 스레드는 획득 한 모니터를 유지합니다. 즉, 스레드가 현재 동기화 된 블록 또는 메소드에있는 경우 다른 스레드가이 블록 또는 메소드를 입력 할 수 없습니다. 다른 스레드가 t.interrupt ()를 호출하면 휴면 스레드를 깨 웁니다. sleep은 정적 메소드이므로 항상 현재 스레드 (sleep 메소드를 실행중인 스레드)에 영향을 미칩니다. 일반적인 실수는 t.sleep ()을 호출하는 것입니다. 여기서 t는 다른 스레드입니다. 그럼에도 불구하고 t 스레드가 아닌 현재 스레드입니다.
object.wait () 는 현재 스레드를 sleep ()과 같은 "Not Runnable"상태로 보내지 만 비틀어 놓습니다. 스레드가 아닌 객체에서 대기가 호출됩니다. 이 개체를 "잠금 개체"라고합니다. 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:
Synchronized:
Hold lock:
Wake-up condition:
Usage:
참조 : diff sleep
andwait
간단히 말해서, wait is wait 다른 스레드가 당신을 호출 할 때까지 잠자는 동안 지정된 시간 동안 "다음 명령문을 실행하지 않습니다".
또한 sleep은 Thread 클래스에서 정적 메서드이며 스레드에서 작동하지만 wait ()는 Object 클래스에 있고 객체에서 호출됩니다.
다른 점은 일부 객체에서 대기를 호출하면 관련된 스레드가 객체를 동기화 한 다음 대기합니다. :)
wait
및 sleep
방법은 매우 다릅니다 :
그것에 대해 생각해 보니, 이름은 그 점에서 혼란 스럽습니다. 그러나 sleep
표준 이름이고 wait
등이다 WaitForSingleObject
또는 WaitForMultipleObjects
윈의 API에.
이 게시물에서 : http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-java/
1) wait () 메소드를 호출하는 스레드는 보유한 잠금을 해제합니다.
2) 다른 스레드가 동일한 잠금에서 notify () 또는 notifyAll () 메소드를 호출하면 스레드가 잠금을 다시 얻습니다.
3) wait () 메소드는 동기화 된 블록 내에서 호출되어야합니다.
4) wait () 메소드는 항상 객체에서 호출됩니다.
5) 대기중인 스레드는 notify () 또는 notifyAll () 메소드를 호출하여 다른 스레드에 의해 깨어날 수 있습니다.
6) wait () 메소드를 호출하려면 스레드에 객체 잠금이 있어야합니다.
1) sleep () 메소드를 호출하는 스레드는 보유하고있는 잠금을 해제하지 않습니다.
2) sleep () 메소드는 동기화 된 블록 내부 또는 외부에서 호출 될 수 있습니다.
3) sleep () 메소드는 항상 스레드에서 호출됩니다.
4) 잠자는 실을 다른 실로 깨울 수 없습니다. 그렇게하면 스레드가 InterruptedException을 throw합니다.
5) sleep () 메소드를 호출하기 위해 스레드는 객체 잠금을 가질 필요가 없습니다.
수면 / 인터럽트와 대기 / 알림의 잠재적 인 큰 차이점 중 하나는
interrupt()
동안 sleep()
항상 예외 (예 : InterruptedException ) 가 발생합니다.notify()
동안 전화 wait()
하지 않습니다.필요하지 않은 예외를 생성하는 것은 비효율적입니다. 스레드가 높은 속도로 서로 통신하는 경우 인터럽트를 항상 호출하면 많은 예외가 발생합니다. 이는 총 CPU 낭비입니다.
당신이 맞습니다-Sleep ()은 스레드가 "슬립"하게하고 CPU는 다른 스레드 (컨텍스트 전환이라고도 함)를 처리하지만 CPU가 현재 스레드를 처리하는 CPU를 계속 유지한다고 생각합니다.
우리는 다른 사람이 CPU를 사용하지 않는 동안 CPU를 사용하는 것이 합리적으로 보일 수 있지만 실제로는 컨텍스트 전환에 오버 헤드가 있습니다-수면 시간에 따라 CPU 사이클이 더 비쌀 수 있습니다 스레드를 단순히 몇 ms 동안 아무것도하지 않는 것보다 스레드를 전환하는 것입니다.
또한 sleep은 컨텍스트 전환을 강제합니다.
또한 일반적으로 컨텍스트 전환을 제어 할 수 없습니다. 대기 중 OS가 다른 스레드를 처리하도록 선택할 수 있습니다 (더 이상 대기 할 경우).
interrupt
입니다. 종료 시간은 n
입니다 wait(n)
. ¶¶ 지금은 8 년이 지났지 만 아직 아무도 답이 없습니다!
방법은 다른 것들에 사용됩니다.
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
어,로를, sleep
하지만 당신은 잠금 귀찮게해야합니다.
두 방법 모두 절전 / 대기 중에 CPU를 사용하지 않습니다.
메소드는 유사한 구성을 사용하지만 동일한 방식으로 네이티브 코드를 사용하여 구현됩니다.
자신을 찾으십시오. 기본 메소드의 소스 코드를 사용할 수 있습니까? 파일 /src/share/vm/prims/jvm.cpp
은 시작점입니다 ...
Thread.sleep(big_num)
중단 되어야 합니다. 통보 Object.wait(small_num)
받을 수 있습니다.
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 ()입니다. 당신이 일하지 않은 시간, 당신은 잠을 자고 있습니다. 여기도 마찬가지입니다.
기다림(). 당신이 내려 놓고 기다리는 동안 또 다른 의미를 취할 때, 그것은 기다립니다
당신은 한 번에 둘 이상을 재생할 수없는 플레이어와 같은 영화 또는 시스템에서 아무것도 재생합니다. 즉, 닫고 다른 사람의 영화 나 노래를 선택하면 대기라고합니다.
wait
잠금을 해제 sleep
하지 않습니다. 대기 상태의 스레드는 notify
또는 notifyAll
호출 되는 즉시 깨울 수 있습니다. 그러나 sleep
스레드가 잠금을 유지하는 경우 잠자기 시간이 끝나면 자격이 부여됩니다.
InterruptedException
은 Javadoc에서 말하는 것처럼 던져집니다.
필자의 의견으로는 두 메커니즘의 주요 차이점은 휴면 / 인터럽트가 스레드를 처리하는 가장 기본적인 방법이며, 대기 / 알림은 스레드 상호 통신을보다 쉽게 수행 할 수 있도록하는 추상화라는 점입니다. 이것은 수면 / 인터럽트가 무엇이든 할 수 있지만이 특정 작업은 더 어렵다는 것을 의미합니다.
대기 / 알림이 더 적합한 이유는 무엇입니까? 다음은 몇 가지 개인적인 고려 사항입니다.
중앙 집중화를 시행합니다. 단일 공유 객체를 사용하여 스레드 그룹 간의 통신을 조정할 수 있습니다. 이것은 작업을 많이 단순화합니다.
동기화를 시행합니다. 프로그래머가 동기화 된 블록에서 대기 / 알림을 위해 호출을 랩핑하기 때문입니다.
스레드 원점 및 번호와 무관합니다. 이 방법을 사용하면 다른 스레드를 편집하거나 기존 스레드를 추적하지 않고도 스레드를 임의로 추가 할 수 있습니다. 휴면 / 인터럽트를 사용한 경우 먼저 휴면 스레드에 대한 참조를 유지 한 다음 하나씩 수작업으로 중단해야합니다.
실생활의 예로는 고전 식당과 직원들이 의사 소통을하는 데 사용하는 방법이 있습니다. 웨이터는 고객의 요청을 중앙 장소 (코크 보드, 테이블 등)에 남겨두고, 종을 울리면 부엌의 일꾼들이 그러한 요청을받습니다. 코스 준비가 완료되면 주방 직원이 종을 다시 울려 웨이터가 인식하고 고객에게 가져갑니다.
수면에 대한 예는 잠금을 해제하지 않고 대기는 해제합니다.
여기에는 두 가지 클래스가 있습니다.
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로 작성된 싱글 톤 인스턴스는 동일합니다. threadA가 잠금을 해제 할 때까지 threadB가 외부에서 대기 중임을 의미합니다.
이제 Thread.sleep (500); 메소드 및 주석 해제 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 객체를 생성했기 때문에 동일하지 않습니다.
동기화 된 블록에서 호출되어야합니다. wait()
메소드는 항상 동기화 된 블록에서 호출됩니다. 즉, wait()
메소드는 호출 된 오브젝트 전에 오브젝트 모니터를 잠 가야합니다 . 그러나 sleep()
메소드는 외부 동기화 블록에서 호출 할 수 있습니다. 즉 sleep()
메소드에는 객체 모니터가 필요하지 않습니다.
IllegalMonitorStateException : 런타임시 발생하는 wait()
것보다 객체 잠금을 획득하지 않고 메소드를 호출하는 경우IllegalMonitorStateException
sleep()
방법은 결코 같은 예외가 발생하지 않습니다.
어떤 클래스에 속합니까 : wait()
method는 java.lang.Object
클래스에 sleep()
속 하지만 method는 java.lang.Thread
클래스에 속합니다 .
객체 또는 스레드에서 호출 : wait()
메소드는 객체에서 호출되지만 sleep()
메소드는 객체가 아닌 스레드에서 호출됩니다.
스레드 상태 :wait()
객체에서 메소드가 호출 되면 객체의 모니터를 보유한 스레드가 실행 상태에서 대기 상태로 전환되고 해당 객체에서 notify()
또는 notifyAll()
메소드가 호출 된 경우에만 실행 가능한 상태로 돌아갈 수 있습니다 . 그리고 나중에 스레드 스케줄러는 해당 스레드가 실행 가능 상태에서 실행 상태로 이동하도록 스케줄합니다. sleep()
스레드에서 호출 되면 실행 상태에서 대기 상태로 전환되고 절전 시간이되면 실행 가능 상태로 돌아갈 수 있습니다.
동기화 된 블록에서 호출 된 경우 :wait()
메소드가 호출 되면 스레드가 오브젝트 잠금을 벗어납니다. 그러나 sleep()
동기화 된 블록이나 메소드 스레드에서 호출 될 때 메소드는 객체 잠금을 유지하지 않습니다.
추가 참조
wait () 메소드의 Oracle 문서 페이지에서 Object
:
public final void wait()
notify()
메서드 또는 notifyAll()
메서드를 호출 할 때까지 현재 스레드가 대기 하도록합니다. 즉,이 메소드는 단순히 call을 수행하는 것처럼 정확하게 작동합니다 wait(0)
.이 방법은
IllegalMonitorStateException
-현재 스레드가 객체 모니터의 소유자가 아닌 경우
InterruptedException
-현재 스레드가 알림을 대기하기 전이나 기다리는 동안 스레드가 현재 스레드를 중단 한 경우 이 예외가 발생하면 현재 스레드의 중단 된 상태가 지워집니다.
클래스의 sleep () 메소드에 대한 Oracle 문서 페이지에서 Thread
:
public static void sleep(long millis)
이 방법은 다음을 발생시킵니다.
IllegalArgumentException
-밀리 값이 음수 인 경우
InterruptedException
-스레드가 현재 스레드를 중단 한 경우 이 예외가 발생하면 현재 스레드의 중단 된 상태가 지워집니다.
다른 주요 차이점 :
wait()
정적 메소드 sleep()
(클래스 메소드) 와 달리 비 정적 메소드 (인스턴스 메소드)입니다.
wait()
반면 동기화 방법 안에 부여 sleep()
하기 때문에 비 동기화 방법 안에 부여 wait()
방법은 개체의 잠금을 해제하지만 sleep()
또는 yield()
해제하지 lock()
.
sleep()
synchronized
블록이나 메소드 안에있을 수 있습니다 . 대답은 아무것도 설명하지 않습니다.
wait(1000)
는 현재 스레드가 최대 1 초 동안 휴면 상태가 되도록합니다 .
notify()
또는notifyAll()
메소드 호출을 수신하면 1 초 미만으로 휴면 상태가 될 수 있습니다.sleep(1000)
하면 현재 스레드가 정확히 1 초 동안 휴면 상태가 됩니다 .
sleep(1000)
정확히 1 초 동안 잠자기 보장하지 않습니다. 이전에 중단되었을 수 있습니다.
실제로,이 모든 것은 Java 문서에 명확하게 설명되어 있습니다 (그러나 나는 대답을 읽은 후에 만 이것을 깨달았습니다).
http://docs.oracle.com/javase/8/docs/api/index.html :
wait ()-현재 스레드는이 객체의 모니터를 소유해야합니다. 스레드는이 모니터의 소유권을 해제하고 다른 스레드가이 객체의 모니터에서 대기중인 스레드가 notify 메소드 또는 notifyAll 메소드에 대한 호출을 통해 깨어나도록 알릴 때까지 기다립니다. 그런 다음 스레드는 모니터 소유권을 다시 얻을 수있을 때까지 기다렸다가 실행을 다시 시작합니다.
sleep ()-시스템 타이머 및 스케줄러의 정밀도 및 정확성에 따라 현재 실행중인 스레드가 지정된 시간 (밀리 초) 동안 휴면 (일시적으로 실행 중단)되도록합니다. 스레드는 모니터의 소유권을 잃지 않습니다.