1. 概要
このチュートリアルでは、 Threadクラスのメソッドyield()について説明します。
Javaで利用可能な他の並行性イディオムと比較し、最終的にはその実用的なアプリケーションを検討します。
2. yield()の概要
公式ドキュメントが示唆しているように、 収率() 「スケジューラ」に次のことを通知するメカニズムを提供します現在のスレッドは、プロセッサの現在の使用を放棄する用意がありますが、できるだけ早くスケジュールを戻すことを望んでいます。
「スケジューラ」は、この情報を自由に順守または無視でき、実際、オペレーティングシステムによって動作が異なります。
次のコードフラグメントは、各スケジュールの後に生成される同じ優先度の2つのスレッドを表示します。
public class ThreadYield {
public static void main(String[] args) {
Runnable r = () -> {
int counter = 0;
while (counter < 2) {
System.out.println(Thread.currentThread()
.getName());
counter++;
Thread.yield();
}
};
new Thread(r).start();
new Thread(r).start();
}
}
上記のプログラムを複数回実行しようとすると、異なる結果が得られます。 それらのいくつかを以下に示します。
実行1:
Thread-0
Thread-1
Thread-1
Thread-0
実行2:
Thread-0
Thread-0
Thread-1
Thread-1
ご覧のとおり、 yield()の動作は非決定的であり、プラットフォームにも依存します。
3. 他のイディオムとの比較
スレッドの相対的な進行に影響を与えるための他の構成があります。 wait()、 notify()、 notifyAll()が Object クラス、 join()[の一部として含まれています。 Thread クラスの一部としてのX117X]、および Threadクラスの一部としてのsleep()。
それらがyield()とどのように比較されるかを見てみましょう。
3.1. yield()と wait()
- yield()は現在のスレッドのコンテキストで呼び出されますが、 wait()は、同期されたブロックまたはメソッド内の明示的に取得されたロックでのみ呼び出すことができます
- yield()とは異なり、wait ()は、スレッドを再度スケジュールする前に待機する最小期間を指定できます。
- wait()を使用すると、関連するロックオブジェクトで notify()または notifyAll()を呼び出すことにより、いつでもスレッドをウェイクアップできます。
3.2. yield()と sleep()
- yield()は、現在のスレッドの実行をヒューリスティックに一時停止することしかできず、いつスケジュールが戻されるかは保証されませんが、 sleep()はスケジューラーを強制的に一時停止することができますパラメータとして少なくとも言及された期間の現在のスレッドの実行。
3.3. yield()と join()
- 現在のスレッドは、他のスレッドで join()を呼び出すことができます。これにより、現在のスレッドは、他のスレッドが終了するのを待ってから続行します。
- オプションで、現在のスレッドが再開する前に待機する必要がある最大時間を示すパラメーターとして期間を指定できます。
4. yield()の使用法
公式ドキュメントが示唆しているように、 yield()を使用する必要はめったにないため、その動作に照らして目的が明確でない限り、避ける必要があります。
それでも、 yield()の使用には、同時実行制御構造の設計、計算量の多いプログラムでのシステム応答性の向上などが含まれます。
ただし、これらの使用法には、望ましい結果を保証するための詳細なプロファイリングとベンチマークを伴う必要があります。
5. 結論
この簡単な記事では、 Threadクラスのyield()メソッドについて説明し、コードフラグメントを通じてその動作と制限を確認しました。
また、Javaで利用可能な他の並行性イディオムとの比較を検討し、最後に yield()が役立つ可能性のあるいくつかのユースケースを調べました。
いつものように、GitHubでこの記事で提供されている例を確認できます。