Thread.sleep (0) 및 Thread.yield () 문이 동일합니까?
이 두 문장이 동등합니까?
Thread.sleep(0);
Thread.yield();
아니오. 가장 분명한 차이점은 sleep()
(checked) 를 던진다 는 것입니다 InterruptedException
. 실제로 효과는 거의 동일 할 수 있지만 완전히 구현에 따라 다릅니다.
시스템 타이머 세분화로 인해 무시할 수없는 시간 동안 실제로 절전 모드로 전환되는 경우가 많기 때문에 연속으로 백만 번을 수행하면 sleep ()에 훨씬 더 오래 걸릴 것 입니다.
Yield는 현재 스레드를 준비 대기열에 추가하고 다른 스레드를 실행할 수 있도록합니다. 수면은 CPU를 포기한다고 보장되지 않습니다.
이것은 실제로 JVM의 플랫폼과 버전에 따라 다릅니다. 예를 들어 JDK 5 (핫스팟)의 Windows에서 yield ()는 문자 그대로 Sleep (0)으로 구현됩니다. 그러나 제가 기억하는 것처럼 Windows에서는 절전 모드 0이 약간 특별하게 처리됩니다. 그러나 JDK 6에서 yield ()는 SwitchToThread ()로 구현됩니다.
얼마 전에 Thread.yield () 에 대한 몇 가지 정보를 모았습니다 . 여기에는 흥미로운 구현 세부 사항이 포함되어 있습니다. ( 같은 사이트에 모아 놓은 Thread.sleep () 의 내용을보고 싶을 수도 있습니다.)
오픈 JDK 소스 (자바 SE 7)에 대한 다음과 같은 구현을 가지고 Thread.sleep(0)
있는 JVM_Sleep
jvm.cpp의 기능 :
if (millis == 0) {
// When ConvertSleepToYield is on, this matches the classic VM implementation of
// JVM_Sleep. Critical for similar threading behaviour (Win32)
// It appears that in certain GUI contexts, it may be beneficial to do a short sleep
// for SOLARIS
if (ConvertSleepToYield) {
os::yield();
} else {
ThreadState old_state = thread->osthread()->get_state();
thread->osthread()->set_state(SLEEPING);
os::sleep(thread, MinSleepInterval, false);
thread->osthread()->set_state(old_state);
}
}
Thread.yield () 구현에는 다음 코드가 있습니다.
// When ConvertYieldToSleep is off (default), this matches the classic VM use of yield.
// Critical for similar threading behaviour
if (ConvertYieldToSleep) {
os::sleep(thread, MinSleepInterval, false);
} else {
os::yield();
}
그래서 Thread.sleep(0)
및 Thread.yield()
일부 플랫폼에서 동일한 시스템 호출을 호출 할 수 있습니다.
os::sleep
및 os::yield
플랫폼 특정 물건입니다. Linux 및 Windows 모두에서 : os::yield
보다 훨씬 더 간단 것으로 보인다 os::sleep
. 예 : os::yield
Linux 호출 만 sched_yield()
. 그리고 os::sleep
약 70 줄의 코드가 있습니다.
yield ()는 JVM 스레드 스케줄러에게 다른 스레드 시간 조각을 제공해도 좋다고 알려줍니다. 일반적으로 JVM은이 호출을 사용하여 동일한 스레드 우선 순위의 다른 스레드를 활성화합니다. 좋은 선점 형 멀티 스레딩 환경에서 yield ()는 작동하지 않습니다. 그러나 yield () 없이는 하나의 스레드가 모든 CPU를 먹을 수 있기 때문에 협력적인 멀티 스레딩 환경에서는 중요합니다.
sleep (x)는 JVM 스레드 스케줄러에게이 스레드를 능동적으로 절전 모드로 전환하고 최소한 x 밀리 초가 경과 할 때까지 다시 실행하지 않도록 지시합니다.
sleep ()도 yield ()도 동기화 잠금 상태에 대해 아무것도 변경하지 않습니다. 스레드에 잠금이 있고 sleep (1000)을 호출하면 스레드가 깨어나 기 전에 적어도 1 초가 경과합니다. 깨어 나면 잠금을 해제하거나 더 오래 유지할 수 있습니다.
출처 : http://www.jguru.com/faq/view.jsp?EID=425624
유명한 Brian Goetz의 저서 "Java Concurrency in Practice"(2006 년에 출판되었지만 여전히 근본적으로 유효 함)는이 질문에 대해 다음과 같이 말합니다.
Thread.yield와 Thread.sleep (0)의 의미는 정의되지 않았습니다 [JLS17.9]; JVM은이를 no-ops로 구현하거나 스케줄링 힌트로 처리 할 수 있습니다. 특히, Unix 시스템에서 sleep (0)의 의미를 가질 필요는 없습니다. 현재 스레드를 해당 우선 순위에 대한 실행 대기열의 끝에 두어 동일한 우선 순위의 다른 스레드에 양보합니다. 일부 JVM은 이 방법.
나머지는 Javadoc 페이지에서 찾을 수 있습니다.
Thread.Yield는 우선 순위가 낮은 스레드에 CPU 리소스를 포기할 수 있지만 Thread.Sleep (0)은 우선 순위가 같거나 높은 스레드에만 CPU를 포기합니다.
적어도 Windows 플랫폼에서는 :)
Thread.sleep를 () 및 Thread.yield ()는 점을 제외하고 같은 일을 Thread.yield ()가 멀티 프로세서 환경에서 동일한 프로세서에서 실행되는 스레드 만 포기한다.
Thread.Sleep()
프로세스를 깨우는 일종의 타이머를 포함하는 시스템을 생성하기 때문에 약간 더 큰 오버 헤드가 있습니다. (기본적으로 구현에 따라 다름)
결론 Yield()
은 결국 a 를 호출합니다 .
Thread.Yield()
스레드의 차례를 포기하고 다음 라운드에서 얻습니다.
Thread.Sleep(0)
yield를 호출하는 최적화가있을 수 있습니다. (다시 구현)
What yield() is supposed to do is make the currently running thread head back to runnable to allow other threads of the same priority to get their turn. So the intention is to use yield() to promote graceful turn-taking among equal-priority threads. In reality, though, the yield() method isn't guaranteed to do what it claims, and even if yield() does cause a thread to step out of running and back to runnable, there's no guarantee the yielding thread won't just be chosen again over all the others! So while yield() might—and often does—make a running thread give up its slot to another runnable thread of the same priority, there's no guarantee.
yield ()는 스레드가 대기 / 수면 / 차단 상태가되도록하지 않습니다. 기껏해야 yield ()는 스레드를 실행에서 실행 가능하게 만들지 만 다시는 전혀 효과가 없을 수 있습니다.
출처 : SCJP Sun Certified Programmer book
플랫폼 및 구현에 따라 다르며 동등하지 않을 수 있습니다.
아래 스 니펫은 Thread.sleep (0)을 사용할 때 대부분의 경우 출력을 제공합니다.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Thread.yield ()를 사용할 때 대부분 다음을 제공합니다.
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2]
아래 스 니펫을 참조하십시오.
public class CompareSleepZeroAndYield {
private ArrayList<Integer> list1 = new ArrayList<>();
private ArrayList<Integer> list2 = new ArrayList<>();
public ArrayList<Integer> getList1() {
return list1;
}
public ArrayList<Integer> getList2() {
return list2;
}
public CompareSleepZeroAndYield() {
list1.add(0);
list2.add(0);
}
public void tryFieldLock1() {
synchronized (this.list1) {
list1.add(list2.get(list2.size() - 1) + 1);
}
}
public void tryFieldLock2() {
synchronized (this.list2) {
list2.add(list1.get(list1.size() - 1) + 1);
}
}
public static void main(String[] args) {
CompareSleepZeroAndYield obj = new CompareSleepZeroAndYield();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
int count = 10;
while (--count >0) {
obj.tryFieldLock1();
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
// compare above and below
// Thread.yield()
}
System.out.println(obj.getList1());
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
int count = 10;
while (--count >0) {
obj.tryFieldLock2();
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
// compare above and below
// Thread.yield()
}
System.out.println(obj.getList2());
}
});
t1.start();
t2.start();
}
아니요, 동등하지 않으며 위의 설명 외에도 .NET의 Javadoc을 확인해야한다고 생각합니다 yield
. yield
아래 상황이 맞지 않는 한 사용하는 것은 좋은 생각이 아닙니다 .
It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the {@link java.util.concurrent.locks} package.
참고 URL : https://stackoverflow.com/questions/1600572/are-thread-sleep0-and-thread-yield-statements-equivalent
'Programing' 카테고리의 다른 글
R 패키지 개발 버전을 설치하는 방법 github 저장소 (0) | 2020.11.28 |
---|---|
jQuery에 요소가 있는지 정말로 확인해야합니까? (0) | 2020.11.27 |
Ajax 요청 시퀀싱 (0) | 2020.11.27 |
SSH를 통해 Mercurial 저장소 복제 (0) | 2020.11.27 |
여러 div를 한 줄에 표시하지만 여전히 너비를 유지하는 방법은 무엇입니까? (0) | 2020.11.27 |