yield()的主要用途是什么,它与join()和interrupt()有什么不同? [英] What are the main uses of yield(), and how does it differ from join() and interrupt()?
问题描述
我对在Java中使用 yield()
方法有点困惑,特别是在下面的示例代码中。我也读过,yield()是用来防止执行一个线程。
我的问题是:
-
我相信下面的代码在使用
yield()
时和不使用它时会产生相同的输出。这是正确的吗? -
事实上,
yield()
/ p> -
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()执行的任务:
- 如果您只尝试只使用部分CPU ,则可以通过估计线程
拥有多少CPU用于其最后一个处理块,然后睡眠,花费大约
的时间来补偿:参见正在等待进程或资源完成,请执行下列操作:sleep.shtmlrel =nofollow noreferrer> sleep() method;
- 或变得可用,有更有效的方法来实现这一点,
例如通过使用 join()等待另一个线程完成,使用
wait / notify 机制允许一个线程向另一个
发信号通知任务完成,或者理想地通过使用Java 5
并发构造中的一个,例如信号量或阻止队列。
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:
I believe the code below result in the same output both when using
yield()
and when not using it. Is this correct?What are, in fact, the main uses of
yield()
?In what ways is
yield()
different from thejoin()
andinterrupt()
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 callSleep(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 WindowsSwitchToThread()
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屋!