yield() 的主要用途是什么,它与 join() 和 interrupt() 有何不同? [英] What are the main uses of yield(), and how does it differ from join() and interrupt()?

查看:30
本文介绍了yield() 的主要用途是什么,它与 join() 和 interrupt() 有何不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Thread.yield() 方法在 Java 中,特别是在下面的示例代码中.我还读到过,yield() 用于防止线程的执行".

I am a little bit confused about the use of Thread.yield() method in Java, specifically in the example code below. I've also read that yield() is 'used to prevent execution of a thread'.

我的问题是:

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

  1. I believe the code below result in the same output both when using yield() and when not using it. Is this correct?

事实上,yield() 的主要用途是什么?

What are, in fact, the main uses of yield()?

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

In what ways is yield() different from the join() and interrupt() methods?

代码示例:

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(),我都使用上面的代码获得了相同的输出:

I obtain the same output using the code above both with and without using 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 之间更改.

Windows

In the Hotspot implementation, the way that Thread.yield() works has changed between Java 5 and Java 6.

在 Java 5 中,Thread.yield() 调用 Windows API 调用 Sleep(0).这个具有清除当前线程的量程的特殊效果和将其置于优先级队列末尾.其他换句话说,所有具有相同优先级的可运行线程(以及那些优先级更高的线程)优先级)将有机会在下一个被放弃的线程之前运行给定的 CPU 时间.当它最终被重新安排时,它会回来具有完整的完整的量子,但不会继承"任何的屈服时的剩余量.这种行为是一种与睡眠线程的非零睡眠几乎没有什么不同通常会损失 1 个量子值(实际上是 10 或 15 毫秒滴答的 1/3).

In Java 5, Thread.yield() calls the Windows API call Sleep(0). This has the special effect of clearing the current thread's quantum and putting it to the end of the queue for its priority level. In other words, all runnable threads of the same priority (and those of greater priority) will get a chance to run before the yielded thread is next given CPU time. When it is eventually re-scheduled, it will come back with a full full quantum, but doesn't "carry over" any of the remaining quantum from the time of yielding. This behaviour is a little different from a non-zero sleep where the sleeping thread generally loses 1 quantum value (in effect, 1/3 of a 10 or 15ms tick).

在 Java 6 中,此行为已更改.Hotspot VM 现在实现Thread.yield() 使用 Windows SwitchToThread() API 调用.这个电话使当前线程放弃它的当前时间片,而不是它的整个量子.这意味着根据其他的优先级线程,让出线程可以在一个中断中调度回来一段时间后.(有关更多信息,请参阅线程调度部分有关时间片的信息.)

In Java 6, this behaviour was changed. The Hotspot VM now implements Thread.yield() using the Windows SwitchToThread() API call. This call makes the current thread give up its current timeslice, but not its entire quantum. This means that depending on the priorities of other threads, the yielding thread can be scheduled back in one interrupt period later. (See the section on thread scheduling for more information on timeslices.)

在 Linux 下,Hotspot 只需调用 sched_yield().的后果这个电话有点不同,可能比下面更严重视窗:

Under Linux, Hotspot simply calls sched_yield(). The consequences of this call are a little different, and possibly more severe than under Windows:

  • 一个被让出的线程不会获得另一片 CPU 直到所有其他线程都拥有一块 CPU
  • (至少在内核 2.6.8 以后),调度程序的启发式隐式考虑了线程已经让步的事实关于它最近的 CPU 分配——因此,隐含地,一个线程在将来安排时,可以为 yielded 提供更多 CPU.
  • a yielded thread will not get another slice of CPU until all other threads have had a slice of CPU;
  • (at least in kernel 2.6.8 onwards), the fact that the thread has yielded is implicitly taken into account by the scheduler's heuristics on its recent CPU allocation— thus, implicitly, a thread that has yielded could be given more CPU when scheduled in the future.

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

(See the section on thread scheduling for more details on priorities and scheduling algorithms.)

我会说几乎从不.它的行为没有标准定义并且通常有更好的方法来执行您的任务可能想用 yield() 执行:

I would say practically never. Its behaviour isn't standardly defined and there are generally better ways to perform the tasks that you might want to perform with yield():

  • 如果您想仅使用一部分 CPU,您可以通过估计线程使用多少 CPU 以更可控的方式执行此操作已在最后一块处理中使用,然后休眠一些补偿时间:参见 sleep() 方法;
  • 如果您正在等待流程或资源完成或可用,则有更有效的方法来实现这一点,例如通过使用 join() 等待另一个线程完成,使用wait/notify 机制允许一个线程向另一个线程发送信号任务已完成,或者最好使用 Java 5 之一并发结构,例如 Semaphore阻塞队列.
  • if you're trying to use only a portion of the CPU, you can do this in a more controllable way by estimating how much CPU the thread has used in its last chunk of processing, then sleeping for some amount of time to compensate: see the sleep() method;
  • if you're waiting for a process or resource to complete or become available, there are more efficient ways to accomplish this, such as by using join() to wait for another thread to complete, using the wait/notify mechanism to allow one thread to signal to another that a task is complete, or ideally by using one of the Java 5 concurrency constructs such as a Semaphore or blocking queue.

这篇关于yield() 的主要用途是什么,它与 join() 和 interrupt() 有何不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆