Java Thread.sleep(0) 和 Thread.yield() 语句是否等效?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1600572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Are Thread.sleep(0) and Thread.yield() statements equivalent?
提问by Prady
Are these two statement equivalent?
这两个语句是等价的吗?
Thread.sleep(0);
Thread.yield();
采纳答案by Michael Borgwardt
No. The most obvious difference is that sleep()
throws the (checked) InterruptedException
. In practice, the effect may be almost the same, but it's entirely implementation-dependant.
不。最明显的区别是sleep()
抛出 (checked) InterruptedException
。在实践中,效果可能几乎相同,但它完全取决于实现。
I'd wager that doing each a million times in a row would take muchlonger for sleep(), since system timer granularity probably often causes it to actually sleep for a non-negligible amount of time.
我敢打赌,在连续做各一百万次将采取很多更长的睡眠(),因为系统计时器粒度可能经常导致它实际上是一段不可忽略量的睡眠。
回答by z -
Yield adds the current thread to the ready queue and allows other threads to run. Sleep is not guaranteed to relinquish the cpu.
Yield 将当前线程添加到就绪队列并允许其他线程运行。睡眠并不能保证放弃 CPU。
回答by Roberto Aloi
yield() tells the JVM Thread Scheduler that it's OK to give other threads time slices. Usually the JVM uses this call to activate another thread of the same thread priority. In a good preemptive multithreading environment, yield() is a no-op. However, it is important in a cooperative multithreading environment, since without yield(), one thread can eat up all of the CPU.
sleep(x) tells the JVM Thread Scheduler to actively put this thread to sleep and not run it again until at least x milliseconds have elapsed.
Neither sleep() nor yield() change anything about the status of synchronization locks. If your thread has a lock, and you call sleep(1000), then at least a second will elapse before your thread wakes up. When it wakes up it may decide to release the lock -- or it may hold on to it longer.
yield() 告诉 JVM 线程调度程序可以给其他线程时间片。通常 JVM 使用这个调用来激活另一个具有相同线程优先级的线程。在良好的抢占式多线程环境中,yield() 是空操作。但是,这在协作多线程环境中很重要,因为如果没有 yield(),一个线程可能会占用所有 CPU。
sleep(x) 告诉 JVM 线程调度器主动将该线程置于睡眠状态,并且在至少 x 毫秒过去之前不会再次运行它。
sleep() 和 yield() 都不会改变同步锁的状态。如果您的线程有锁,并且您调用 sleep(1000),那么在您的线程唤醒之前至少会过去一秒钟。当它醒来时,它可能会决定释放锁——或者它可能会保持更长时间。
回答by Vitaliy Liptchinsky
Thread.Yield can give up CPU resource to threads with lower priorities, while Thread.Sleep(0) gives up CPU only to threads with equal or higher priorities.
Thread.Yield 可以将 CPU 资源放弃给优先级较低的线程,而 Thread.Sleep(0) 仅将 CPU 分配给具有相同或更高优先级的线程。
At least on Windows platform :)
至少在 Windows 平台上:)
回答by Neil Coffey
This really depends on the platform and version of the JVM. For example, under Windows in JDK 5 (Hotspot), yield() is literally implemented as Sleep(0)-- although a sleep of 0 is treated slightly specially by Windows as I recall. But in JDK 6, yield() is implemented as SwitchToThread().
这实际上取决于 JVM 的平台和版本。例如,在 JDK 5(热点)中的 Windows 下,yield() 实际上是作为 Sleep(0) 实现的——尽管我记得 Windows 对 0 的睡眠略有特殊处理。但是在 JDK 6 中,yield() 被实现为 SwitchToThread()。
I put together some information a while ago on Thread.yield(), including some implementational details that may be of interest. (You might also want to see the stuff on Thread.sleep()I put together on the same site.)
不久前,我在Thread.yield()上汇总了一些信息,包括一些可能感兴趣的实现细节。(您可能还想查看我放在同一站点上的Thread.sleep()上的内容。)
回答by Yochai Timmer
Thread.Sleep()
has a slightly larger overhead because it creates a system that includes some kind of timer that will wake the process. (Depends on implementation basically)
Bottom line it will call a Yield()
in the end.
Thread.Sleep()
有一个稍大的开销,因为它创建了一个系统,其中包含某种可以唤醒进程的计时器。(基本上取决于实现)
底线它最终会调用 a Yield()
。
Thread.Yield()
Will just give-up the thread's turn, and gain it in the next round.
Thread.Yield()
只会放弃线程的回合,并在下一轮获得它。
Thread.Sleep(0)
might have an optimization to just call yield. (Again, implementation)
Thread.Sleep(0)
可能有一个优化,只是调用 yield。(再次,实现)
回答by Grigor Nazaryan
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.
A yield() won't ever cause a thread to go to the waiting/sleeping/ blocking state. At most, a yield() will cause a thread to go from running to runnable, but again, it might have no effect at all.
yield() 应该做的是使当前运行的线程头回到可运行状态,以允许相同优先级的其他线程轮到它们。因此,目的是使用 yield() 来促进同等优先级线程之间的优雅轮换。但实际上,并不能保证 yield() 方法会执行它声称的操作,即使 yield() 确实导致线程退出运行状态并返回到可运行状态,也不能保证让步线程不会只是在所有其他人中再次被选中!因此,虽然yield() 可能——而且经常会——让一个正在运行的线程将其插槽让给另一个具有相同优先级的可运行线程,但并不能保证。
yield() 永远不会导致线程进入等待/睡眠/阻塞状态。最多,yield() 将导致线程从运行状态变为可运行状态,但同样,它可能根本没有效果。
Source: SCJP Sun Certified Programmer book
来源:SCJP Sun 认证程序员书籍
回答by SKi
OpenJDK source (Java SE 7) have the following implementation for Thread.sleep(0)
in JVM_Sleep
function of jvm.cpp:
OpenJDK源码(Java 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);
}
}
And implemtation of Thread.yield() have the following code:
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();
}
So Thread.sleep(0)
and Thread.yield()
may call same system calls in some platforms.
因此Thread.sleep(0)
,Thread.yield()
可能会在某些平台上调用相同的系统调用。
os::sleep
and os::yield
are platform specific stuff.
On both Linux and Windows: os::yield
seems to be much simplier than os::sleep
.
For example: os::yield
of Linux calls only sched_yield()
. And os::sleep
have about 70 lines of code.
os::sleep
并且os::yield
是特定于平台的东西。在 Linux 和 Windows 上:os::yield
似乎比os::sleep
. 例如:os::yield
Linux 只调用sched_yield()
. 并且os::sleep
有大约 70 行代码。
回答by Abdulrahman Awwad
Thread.sleep()and Thread.yield()do the same thing except that Thread.yield()relinquishes only to threads running on the same processor in multiprocessor environment.
Thread.sleep()和Thread.yield()做同样的事情,除了Thread.yield()只放弃在多处理器环境中运行在同一处理器上的线程。
回答by peter.petrov
The famous Brian Goetz's book "Java Concurrency in Practice" (published in 2006 but still fundamentally valid) says the following on this question.
著名的布赖恩·戈茨 (Brian Goetz) 的著作“实践中的 Java 并发”(2006 年出版,但仍然基本有效)对这个问题说了以下内容。
The semantics of Thread.yield and Thread.sleep(0) are undefined [JLS17.9]; the JVM is free to implement them as no-ops or treat them as scheduling hints. In particular, they are not required to have the semantics of sleep(0) on Unix systems — put the current thread at the end of the run queue for that priority, yielding to other threads of the same priority — though some JVMs implement yield in this way.
Thread.yield 和 Thread.sleep(0) 的语义未定义 [JLS17.9];JVM 可以自由地将它们实现为无操作或将它们视为调度提示。特别是,它们不需要在 Unix 系统上具有 sleep(0) 的语义——将当前线程放在该优先级的运行队列的末尾,让步给具有相同优先级的其他线程——尽管一些 JVM 在这边走。
The rest one can find in the Javadoc pages.
其余的可以在 Javadoc 页面中找到。