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

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

问题描述

我对在Java中使用 yield()方法有点困惑,特别是在下面的示例代码中。我也读过,yield()是用来防止执行一个线程。



我的问题是:


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


  2. 事实上, yield() / p>


  3. yield() / code>和 interrupt()方法?


代码示例:

  public class MyRunnable implements Runnable {

public static void main [] 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()

  main 
内部main
内部main
内部main
内部main
内部运行
内部运行
内部运行
内部运行
内部运行


解决方案

a href =http://www.javamex.com/tutorials/threads/yield.shtml =nofollow noreferrer> http://www.javamex.com/tutorials/threads/yield.shtml


Windows



在Hotspot实现中, Thread.yield()在Java 5和Java 6之间更改



在Java 5 , Thread.yield()调用Windows API调用 Sleep(0)。这个
具有清除当前线程的量子
的特殊效果,将其置于队列的优先级 / strong>。在其他
字中,具有相同优先级的所有可运行线程(以及优先级大于
的所有可运行线程)在给定CPU时间的情况下,将在获得线程之前获得运行的机会
。当它最终重新调度时,它将返回
,其中包含完整的全量子,但不会从产生时间结转任何
剩余量。这个行为是一个
与非零睡眠有点不同,睡眠线程
通常丢失1个量子值(实际上是1/3的10或15ms的tick)。



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



Linux



在Linux下,Hotspot只需调用 sched_yield code>。
这个调用的后果有点不同,并且可能比
下更严重Windows:




  • 线程将不会获得另一个CPU片段,直到所有其他线程都有一片CPU ;

  • (至少在内核2.6 .8向前),线程已经产生的事实被调度器的启发式
    隐含地考虑在其最近的CPU分配上,因此,隐含地,产生
    的线程可以被给予更多的CPU,预定在未来。



(请参阅线程调度以了解优先级
和调度算法的更多详细信息。)



何时使用 yield()



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





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

My questions are:

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

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

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

The code example:

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();
      }
   }
}

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

解决方案

Source: http://www.javamex.com/tutorials/threads/yield.shtml

Windows

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

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).

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

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

  • 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.)

When to use 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():

  • 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天全站免登陆