Java Thread.yield()の簡単な紹介
1. 概要
このチュートリアルでは、Threadクラスのメソッドyield()について説明します。
これをJavaで利用可能な他の並行性イディオムと比較し、最終的にはその実用的なアプリケーションを探ります。
2. yield()の概要
公式ドキュメントが示唆しているように、yield()は、「スケジューラー」にthe current thread is willing to relinquish its current use of processor but it’d like to be scheduled back soon as possible.を通知するメカニズムを提供します。
「スケジューラ」はこの情報を自由に遵守または無視することができ、実際、オペレーティングシステムによって動作が異なります。
次のコードフラグメントは、各スケジュールの後に生じる同じ優先度の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. 他のイディオムとの比較
スレッドの相対的な進行に影響する他の構成要素があります。 それらには、Objectクラスの一部としてのwait()、notify()、およびnotifyAll()、Threadクラスの一部としてのjoin()、およびsleep()が含まれます。 Threadクラスの一部として。
それらが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()が役立つ可能性のあるいくつかのユースケースを調べました。
いつものように、この記事のover on GitHubで提供されている例を確認できます。