Mic*_*rdt 44

不.最明显的区别是sleep()抛出(已检查)InterruptedException.在实践中,效果可能几乎相同,但它完全依赖于实现.

我敢打赌,在连续做各一百万次将采取很多更长的睡眠(),因为系统计时器粒度可能常常导致其实际睡眠时间的不可忽略的量.

  • @Geek:让'sleep(0)`真正意味着"根本不睡觉"会需要额外的逻辑来使它成为无操作而不是像任何其他数字一样对待0,在这种情况下它意味着"进入睡眠状态"并立即再次唤醒" - **也*让操作系统安排其他线程.由于专门处理这种边缘情况没有明显的好处,我希望大多数实现者不要这样做. (3认同)
  • @Michael你写道"在实践中,效果可能几乎相同".通过阅读Javadocs,我不清楚问题本身的相关性,也不清楚*在实践中*效果*可能是*相同对于两个调用`Thread.sleep(0)`和`Thread.yield()`?"Thread.sleep(0)"是不是意味着根本不睡觉?如果答案是肯定的,那么如何将它等同于`Thread.yield()`,它只是向OS调度程序发送信号以安排其他线程? (2认同)
  • 像任何其他数字一样对待0可能不会意味着,"......立即再次醒来." 它更可能意味着,"转到调度程序堆的顶部,然后在下一个调度程序心跳滴答中等待运行__如果零被视为任何其他数字,那么`sleep(0)`可能会睡眠几十毫秒. (2认同)

z *_* - 32

Yield将当前线程添加到就绪队列并允许其他线程运行.睡眠不能保证放弃cpu.

  • @NeilCoffey你知道帖子的顺序是随机的吗? (7认同)

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

  • 非规范性参考.其中大部分都不在Javadoc中,而关于"JVM线程调度程序"的部分多年来一直是虚构的. (2认同)

pet*_*rov 7

着名的Brian Goetz的着作"Java Concurrency in Practice"(2006年出版,但仍然基本有效)在这个问题上说了以下内容.

Thread.yield和Thread.sleep(0)的语义未定义[JLS17.9]; JVM可以自由地将它们实现为no-ops或将它们视为调度提示.特别是,它们不需要在Unix系统上具有sleep(0)的语义 - 将当前线程放在该优先级的运行队列的末尾,产生相同优先级的其他线程 - 尽管一些JVM实现了产量这条路.

其余人可以在Javadoc页面中找到.