2つのプロセッサを搭載したマシンで2つのスレッドが実行されている状況で、これらのスレッドの1つ内でThread.yield()
を呼び出した場合、何も起こらないのは当然のことです(スケジューラは基本的に要求を無視します)。実行中のスレッドを処理するのに十分なプロセッサがあるからですか?
スレッドがThread.yield()
メソッドを呼び出すときはいつでも、スレッドスケジューラに、実行を一時停止する準備ができているというヒントを与えます。スレッドスケジューラは、このヒントを自由に無視できます。
スレッドがyieldメソッドを実行する場合、スレッドスケジューラは、このスレッドと同じまたは高い優先度を持つ実行可能な(実行待ちの)スレッドがあるかどうかを確認します。プロセッサが優先順位の高いまたは同じスレッドを見つけると、新しいスレッドに切り替わります。そうでない場合、現在のスレッドは実行を続けます。
あなたの例では、すべてのスレッドにサービスを提供するのに十分なプロセッサがあります(スレッドは実行可能であり、実行可能な状態で待機していません)。 Thread.yield()
は何もせず、スレッドは実行を継続します。
Microsoft DOTNetからのWindowsに関するメモ:
このメソッドは、プラットフォームの呼び出しを使用してネイティブのWin32 SwitchToThread 関数を呼び出すのと同じです。
譲渡は、呼び出しスレッドを実行しているプロセッサに限定されます。オペレーティングシステムは、そのプロセッサがアイドル状態であるか、優先順位の低いスレッドを実行している場合でも、実行を別のプロセッサに切り替えません。現在のプロセッサで実行する準備ができている他のスレッドがない場合、オペレーティングシステムは実行を生成しません
したがって、状況によっては注意が必要な場合があります。
Thread.yield()
は廃止されました。 cooperative multitaskingを実装するプラットフォーム、またはグリーンスレッド、それを呼び出す意味はありません。
標準ライブラリ Thread.yield()
のJavadocは、yield()
が何もする必要がないことを効果的に示しています。
Thread::yield
はThread::onSpinWait
に置き換える必要があると常に思っていました(Java 9以降)-使用方法を見るまでは、これは「弱い」歩留まりの形式にすぎませんof both in StampedLock
:
else if ((LockSupport.nextSecondarySeed() & OVERFLOW_YIELD_RATE) == 0)
Thread.yield();
else
Thread.onSpinWait();
return 0L;
だから私はそれが時代遅れだとは思わない。内部的にはjdkソースでは多くの使用法があり、比較的新しいForkJoinPool
でもThread::yield
の使用法があります。
実際には、忙しいスピンの中でThread::onSpinWait
のみを使用しました-その名前からalt leastであるため-いつ使用するかは非常に明確です。一方、譲歩はそうではありません-それで、いつ、どのようにそれを使用するかははっきりとはわかりません。
ちょうど私の0.02 $。