gpt4 book ai didi

java - yield() 的主要用途是什么,它与 join() 和 interrupt() 有何不同?

转载 作者:IT老高 更新时间:2023-10-28 11:28:50 31 4
gpt4 key购买 nike

我对 Thread.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

最佳答案

来源: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.

关于java - yield() 的主要用途是什么,它与 join() 和 interrupt() 有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6979796/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com