Java Thread.yield()の簡単な紹介

1.概要

このチュートリアルでは、 Thread クラスのメソッド yield() を調べます。

私たちはそれをJavaで利用可能な他の並行性イディオムと比較して、そして最終的にそれの実用的なアプリケーションを探ります。

2. __yield()の概要

公式文書が示唆しているように、 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.他の慣用句との比較

スレッドの相対的な進行に影響を与えるための他の構成要素があります。それらには、 Object クラスの一部としての wait() notify() 、および notifyAll() Thread クラスの一部としての join() 、および Thread クラスの一部としての sleep() が含まれます。

それらが yield() とどのように比較されるのかを見てみましょう。

3.1. yield() vs wait()

  • yield() が現在のスレッドのコンテキストで呼び出されている間、

wait() は、明示的に獲得されたロック内でのみ呼び出すことができます。 同期ブロックまたはメソッド ** yield() とは異なり、wait __() __でaを指定することは可能です。

スレッドをスケジュールしようとする試みの前に待機する最小期間 再び ** wait() を使うと、いつでもスレッドを起こすことができます。

当該ロックオブジェクトに対する notify() または notifyAll() の呼び出し

3.2. yield() vs sleep()

  • __yield()は、一時停止を試みるヒューリスティックな試みしかできません。

sleep() は、現在のスレッドの実行がいつスケジュールされるのかを保証せずに実行します。スケジューラは、少なくともそのパラメータとして指定された期間、現在のスレッドの実行を中断することができます。

3.3. yield() vs join()

  • 現在のスレッドは、他のスレッドで join() を呼び出すことができます。

現在のスレッドは先へ進む前に他のスレッドが死ぬのを待つ ** オプションとして、パラメータとして期間を指定できます。

現在のスレッドが再開するまでに待機する最大時間を示します

4. __yield()の使い方

公式文書では yield() を使用する必要はめったにないことが示唆されているため、その動作を考慮して目的が明確に示されていない限り、避けるべきです。

それにもかかわらず、__yield()の用途には、並行処理制御構造の設計、計算量の多いプログラムなどにおけるシステムの応答性の向上などがあります。

ただし、これらの用途には、望ましい結果を確実にするための詳細なプロファイリングとベンチマークを伴う必要があります。

5.まとめ

この短い記事では、 Thread クラスの yield() メソッドについて説明し、その動作と制限事項をコードの一部として説明しました。

また、Javaで利用可能な他の並行性イディオムとの比較も検討し、最後に yield() が役に立つ可能性があるいくつかのユースケースについて調べました。

いつものように、この記事https://github.com/eugenp/tutorials/tree/master/core-java-concurrency[GitHubについて]で提供されている例をチェックすることができます。