如果我们有足够的处理器来服务所有线程,那么Thread.yield()会做任何事情吗?

时间:2019-05-08 15:15:07

标签: java multithreading concurrency java-threads thread-synchronization

如果我们在具有两个处理器的机器上有两个正在运行的线程,并且在其中一个线程中调用Thread.yield(),是否就意味着什么都不会发生(调度程序实际上将忽略该请求) ),因为我们有足够的处理器来服务正在运行的线程?

3 个答案:

答案 0 :(得分:25)

每当线程调用Thread.yield()方法时,它都会向线程调度程序提示已准备好暂停其执行。线程调度程序可以随意忽略此提示。

如果有任何线程执行yield方法,则线程调度程序将检查是否有任何可运行(等待执行)线程的优先级与此线程相同或更高。如果处理器发现具有更高或相同优先级的任何线程,则它将切换到新线程。如果没有,则当前线程继续执行。

由于在您的示例中,您有足够的处理器来服务所有线程(它们正在运行,而不是在可运行状态下等待); Thread.yield()将不执行任何操作,您的线程将继续执行。

Microsoft DOTNet上有关Windows的注释:

  

此方法等效于使用平台调用来调用本机   Win32 SwitchToThread函数。

     

收益仅限于执行调用的处理器   线。操作系统不会将执行切换到另一个   处理器,即使该处理器处于空闲状态或正在运行一个   优先级较低。如果没有其他准备就绪的线程   在当前处理器上执行,操作系统不会产生   执行

因此在某些情况下可能会有警告。

答案 1 :(得分:12)

Thread.yield()已过时。除非您的程序要在实现 cooperative multitasking 的平台上运行,或者在仍使用 green threads 的JVM上运行,否则没有任何意义。调用它。

标准库Javadoc for Thread.yield()有效地表明yield()根本不需要做任何事情。

答案 2 :(得分:6)

我一直认为Thread::yield应该替换为Thread::onSpinWait(自Java 9开始)-这只是“弱化”收益的一种形式,直到我看到 both < / em>在StampedLock中:

    else if ((LockSupport.nextSecondarySeed() & OVERFLOW_YIELD_RATE) == 0)
        Thread.yield();
    else
        Thread.onSpinWait();
    return 0L;

所以我不认为它已经过时了。在jdk源内部,它有许多用法,即使是相对较新的ForkJoinPool也有Thread::yield用法。

在实践中,我只在忙碌的旋转中使用过Thread::onSpinWait -因为它的名称至少 alt -何时使用它是非常清楚的。另一方面,收益率不是-因此我无法确定何时以及如何使用它。

我的0.02美元。