Pra*_*ady 63 java multithreading
这两个陈述是否相同?
Thread.sleep(0);
Thread.yield();
Run Code Online (Sandbox Code Playgroud)
Mic*_*rdt 44
不.最明显的区别是sleep()抛出(已检查)InterruptedException.在实践中,效果可能几乎相同,但它完全依赖于实现.
我敢打赌,在连续做各一百万次将采取很多更长的睡眠(),因为系统计时器粒度可能常常导致其实际睡眠时间的不可忽略的量.
Nei*_*fey 30
这实际上取决于JVM的平台和版本.例如,在JDK 5(Hotspot)中的Windows下,yield()实际上是作为Sleep(0)实现的 - 尽管我记得睡眠为0时稍微特别被Windows处理.但在JDK 6中,yield()实现为SwitchToThread().
我刚才在Thread.yield()上汇总了一些信息,包括一些可能感兴趣的实现细节.(您可能还希望在Thread.sleep()上看到我放在同一站点上的内容.)
SKi*_*SKi 13
OpenJDK源代码(Java SE 7)Thread.sleep(0)在JVM_Sleepjvm.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);
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
因此Thread.sleep(0),Thread.yield()可以在某些平台上调用相同的系统调用.
os::sleep并且os::yield是平台特定的东西.在Linux和Windows上:os::yield似乎比简单得多os::sleep.例如:os::yield仅限Linux调用sched_yield().并且os::sleep有大约70行代码.
Rob*_*loi 10
yield()告诉JVM线程调度程序,给其他线程提供时间片是可以的.通常,JVM使用此调用来激活具有相同线程优先级的另一个线程.在一个良好的抢占式多线程环境中,yield()是一个无操作.但是,它在协作多线程环境中很重要,因为没有yield(),一个线程可以占用所有CPU.
sleep(x)告诉JVM线程调度程序主动将此线程置于休眠状态,并且在至少经过x毫秒之前不再运行它.
sleep()和yield()都不会改变有关同步锁状态的任何信息.如果你的线程有一个锁,你调用sleep(1000),那么在你的线程唤醒之前至少会经过一秒钟.当它醒来时,它可能决定释放锁定 - 或者它可能会持续更长时间.
消息来源: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页面中找到.