一尘不染

yield()的主要用途是什么,它与join()和interrupt()有何区别?

java

yield()对Java 中方法的使用有些困惑,尤其是在下面的示例代码中。我也读过yield()是“用来防止执行线程的”。

我的问题是:

  1. 我相信下面的代码在使用yield()和不使用时都会产生相同的输出。这样对吗?

  2. 实际上,的主要用途是yield()什么?

  3. 在哪些方面yield()从不同join()interrupt()方法?

代码示例:

public class MyRunnable implements Runnable {

   public static void main(String[] args) {
      Thread t = new Thread(new MyRunnable());
      t.start();

      for(int i=0; i<5; i++) {
          System.out.println("Inside main");
      }
   }

   public void run() {
      for(int i=0; i<5; i++) {
          System.out.println("Inside run");
          Thread.yield();
      }
   }
}

无论是否使用,我都使用上面的代码获得相同的输出yield()

Inside main
Inside main
Inside main
Inside main
Inside main
Inside run
Inside run
Inside run
Inside run
Inside run

阅读 214

收藏
2020-09-08

共1个答案

一尘不染

资料来源: http :
//www.javamex.com/tutorials/threads/yield.shtml

视窗

在Hotspot实现中,Thread.yield()Java 5和Java 6之间的工作方式发生了变化。

在Java 5中,Thread.yield()调用Windows API调用Sleep(0)。这具有 清除当前线程的数量 并将
放在优先级级别
的队列末端
的特殊效果。换句话说,具有相同优先级的所有可运行线程(以及具有更高优先级的那些线程)将有机会在下一个给定的CPU时间之前让出线程运行。当最终对其进行重新计划时,它将返回完整的完整量子,但不会从屈服之时“继承”任何剩余的量子。此行为与非零睡眠略有不同,在非零睡眠中,睡眠线程通常会丢失1个量子值(实际上是10毫秒或15毫秒滴答的1/3)。

在Java 6中,此行为已更改。现在,热点VM Thread.yield()使用Windows
SwitchToThread()API调用实现。该调用使当前线程 放弃其 当前时间片 ,而不是其整个 时间片
。这意味着,可以根据其他线程的优先级, 在一个中断周期后将回退 线程 调度回去
。(有关时间片的更多信息,请参见线程调度部分。)

的Linux

在Linux下,热点仅调用sched_yield()。此调用的结果略有不同,并且可能比Windows下更为严重:

  • 直到 所有 其他线程都具有一个 CPU片时,产生的线程才会获得另一个CPU ;
    * (至少在内核2.6.8及更高版本中),调度程序在其最近的CPU分配上的试探法隐含地考虑了线程已产生的事实,因此,隐式地,在执行以下操作时,可以给已产生的线程更多的CPU资源:未来。

(有关优先级和调度算法的更多详细信息,请参见线程调度部分。)

什么时候使用yield()

几乎不会 说。它的行为不是标准定义的,通常有更好的方法可以执行您可能要使用yield()执行的任务:

  • 如果您 尝试 使用一部分CPU ,则可以通过控制线程在最后一个处理块中使用了多少CPU,然后 休眠
    一段时间来进行补偿,以更可控的方式进行操作:请参见的睡眠()方法;
  • 如果您正在 等待进程或资源
    完成或变得可用,则有更有效的方法来完成此操作,例如通过使用join()等待另一线程完成,使用等待/通知机制允许一个线程通知另一个任务已完成,或者最好使用Java
    5并发结构之一(例如信号量阻塞队列)来通知任务。
2020-09-08