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

Does Thread.yield() do anything if we have enough processors to service all threads?

如果我们在一台有两个处理器的机器上有两个 运行 线程的情况,我们在其中一个线程中调用 Thread.yield(),是否按理说什么都不会发生(调度程序基本上会忽略请求)因为我们有足够的处理器来服务 运行 个线程?

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

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

因为在您的示例中,您有足够的处理器来为所有线程提供服务(它们是 运行,而不是在可运行状态下等待); Thread.yield() 什么都不做,您的线程将继续执行。

有关 Windows 的说明,来自 Microsoft DOTNet:

This method is equivalent to using platform invoke to call the native Win32 SwitchToThread function.

Yielding is limited to the processor that is executing the calling thread. The operating system will not switch execution to another processor, even if that processor is idle or is running a thread of lower priority. If there are no other threads that are ready to execute on the current processor, the operating system does not yield execution

所以在某些情况下可能会有警告。

Thread.yield() 已过时。除非你的程序要在实现 cooperative multitasking or on a JVM that still uses green threads 的平台上 运行,否则调用它是没有意义的。

标准库 Javadoc for Thread.yield() 实际上说 yield() 根本不需要做任何事情。

我一直认为 Thread::yield 应该替换为 Thread::onSpinWait(因为 java 9)——这只是“较弱”收益的一种形式,直到我看到一个用法在 StampedLock

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

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

的用法

实际上,我只在busy spin里面用过Thread::onSpinWait——因为至少从名字上看——什么时候用它是很清楚的;另一方面, yield 不是 - 所以我不能确定何时以及如何使用它。

只是我的 0.02 美元。