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

Dav*_*ave 39 java concurrency multithreading thread-synchronization java-threads

如果我们在具有两个处理器的机器上有两个正在运行的线程,并且Thread.yield()在其中一个线程中调用,那么是否有理由不做任何事情(调度程序实际上会忽略请求),因为我们有足够的处理器来服务正在运行的线程?

Gui*_* F. 26

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

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

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

Microsoft DOTNet提供的有关Windows的注释:

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

屈服仅限于执行调用线程的处理器。操作系统不会将执行切换到另一个处理器,即使该处理器处于空闲状态或正在运行优先级较低的线程也是如此。如果没有其他线程可以在当前处理器上执行,则操作系统不会执行

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

  • 请注意,您的操作系统肯定会运行许多其他进程,并且某些进程可能需要CPU时间。 (4认同)
  • @ Dave,Re,“ ...触摸处理器数量...”处理器数量无关。如果Thread.yield()根本不执行任何操作,它会告诉调度程序调用者(a)仍有工作要做,(b)_不希望_放弃正在运行的处理器,但是(c)是_愿意_放弃处理器_if_其他一些线程想要它。唯一重要的处理器是调用者正在其上运行的处理器。唯一重要的数字是希望处理器在其上运行的其他线程的数目(具体来说,该数目是零还是大于零)。 (4认同)

Sol*_*low 13

Thread.yield()已过时。除非您的程序要在实现协作多任务的平台上运行,或者在仍使用绿色线程的JVM上运行,否则调用它是没有意义的。

有效的标准库JavadocThread.yield()表示yield()根本不需要执行任何操作。

  • 我怀疑它已经过时了-在内部查看jdk类-它的许多用法。 (4认同)

Eug*_*ene 7

我一直认为Thread::yield应该被替换Thread::onSpinWait(由于Java 9) -但这只是一个“弱”产量的形式,直到我看到的使用StampedLock

    else if ((LockSupport.nextSecondarySeed() & OVERFLOW_YIELD_RATE) == 0)
        Thread.yield();
    else
        Thread.onSpinWait();
    return 0L;
Run Code Online (Sandbox Code Playgroud)

因此,我认为它不是过时的。在jdk源代码内部,它有许多用法,即使相对较新的ForkJoinPool用法也有Thread::yield

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

只是我的0.02美元。