我yield()对Java 中方法的使用有些困惑,尤其是在下面的示例代码中。我也读过yield()是“用来防止执行线程的”。
yield()
我的问题是:
我相信下面的代码在使用yield()和不使用时都会产生相同的输出。这样对吗?
实际上,的主要用途是yield()什么?
在哪些方面yield()从不同join()和interrupt()方法?
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
资料来源: 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并发结构之一(例如信号量或阻塞队列)来通知任务。
在Hotspot实现中,Thread.yield()Java 5和Java 6之间的工作方式发生了变化。
Thread.yield()
在Java 5中,Thread.yield()调用Windows API调用Sleep(0)。这具有 清除当前线程的数量 并将 其 放在优先级级别 的队列末端 的特殊效果。换句话说,具有相同优先级的所有可运行线程(以及具有更高优先级的那些线程)将有机会在下一个给定的CPU时间之前让出线程运行。当最终对其进行重新计划时,它将返回完整的完整量子,但不会从屈服之时“继承”任何剩余的量子。此行为与非零睡眠略有不同,在非零睡眠中,睡眠线程通常会丢失1个量子值(实际上是10毫秒或15毫秒滴答的1/3)。
Sleep(0)
在Java 6中,此行为已更改。现在,热点VM Thread.yield()使用Windows SwitchToThread()API调用实现。该调用使当前线程 放弃其 当前时间片 ,而不是其整个 时间片 。这意味着,可以根据其他线程的优先级, 在一个中断周期后将回退 线程 调度回去 。(有关时间片的更多信息,请参见线程调度部分。)
SwitchToThread()
在Linux下,热点仅调用sched_yield()。此调用的结果略有不同,并且可能比Windows下更为严重:
sched_yield()
(有关优先级和调度算法的更多详细信息,请参见线程调度部分。)
我 几乎不会 说。它的行为不是标准定义的,通常有更好的方法可以执行您可能要使用yield()执行的任务: