Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaの同時実行性 – Thread.yield()メソッドの仕組みと使い方

yield()メソッドとは

java.lang.Thread.yield()メソッドは、現在実行中のスレッドが自発的にCPUの使用権を手放し、より優先度の高い他のスレッドに実行の機会を譲るよう、スレッドスケジューラにヒントを伝えるためのメソッドです。処理に時間がかかっている重要度の低いスレッドよりも、優先して実行すべきスレッドを先に進めたい場面で利用されます。

スレッドがyield()を呼び出すと、「自分の実行を一時停止してもよい」という合図がスケジューラに送られます。ただし、この合図を受け入れるか無視するかはスケジューラの判断に委ねられており、必ず譲るとは限らない点に注意が必要です。

yield()が実行されると、スケジューラは同じ優先度、またはそれ以上の優先度を持つスレッドが存在するかどうかを確認します。該当するスレッドが存在すれば、現在のスレッドは「実行可能(Runnable)」状態へ移行し、代わりにそのスレッドへプロセッサリソースが割り当てられます。

yield()メソッドの構文

public static native void yield()

それでは、実際のコード例を見てみましょう。

サンプルコード

import java.lang.*;
class Demo extends Thread{
    public void run(){
        for (int i=0; i<3 ; i++)
        System.out.println("In control of " + Thread.currentThread().getName() + " thread");
    }
}
public class Demo_one{
    public static void main(String[]args){
        Demo my_obj = new Demo();
        my_obj.start();
        for (int i=0; i<3; i++){
            Thread.yield();
            System.out.println("In control of " + Thread.currentThread().getName() + " thread");
        }
    }
}

実行結果

In control of main thread
In control of main thread
In control of main thread
In control of Thread-0 thread
In control of Thread-0 thread
In control of Thread-0 thread

コードの解説

この例では、DemoクラスがThreadクラスを継承しており、run()メソッド内でループ処理を行いながら、getName()メソッドを使って自身のスレッド名を取得して表示しています。

Demo_oneクラスのmain()メソッドでは、Demoクラスのインスタンスを生成し、start()メソッドでスレッドを起動しています。メインスレッド側でも同様にループ処理を行い、各繰り返しのたびにThread.yield()を呼び出して実行権の譲渡を試みています。

この結果からも分かるように、yield()の効果は環境やタイミングによって変化します。あくまでスケジューラへの「提案」であり、実行順序を強制するものではない点を理解しておきましょう。

yield()メソッド利用時の注意点

  • yield()によってスレッドが実行権を手放した後は、複数のスレッドがプロセッサリソースを奪い合う状態になります。どのスレッドが先に実行されるかを指定・保証する方法はありません。

  • yield()を実行すると、スレッドの状態は「実行中(Running)」から「実行可能(Runnable)」へ遷移します。

  • yield()が意味を持つのは、プラットフォームがプリエンプティブ(横取り型)スケジューリングをサポートしている場合のみです。協調的スケジューリングの環境では期待どおりに動作しません。

  • スレッドが実行を一時停止しても、再び実行機会がすぐ得られるかどうかは保証されません。それはスケジューリングアルゴリズムとスレッドスケジューラの実装に依存します。

なお、公式ドキュメント上もyield()はほとんど役に立たないデバッグ用の手段とされており、実運用ではsleep()や適切な同期機制を検討するのが一般的です。

  1. JavaのisDaemon()メソッドとは?デーモンスレッドの判定方法と重要性を解説

    Javaにおけるデーモンスレッド(daemon thread)とは、低優先度のバックグラウンドスレッドのことです。主にJVMによって生成され、ガベージコレクション(GC)などの裏方の処理を担当します。デーモンスレッドの最大の特徴は、ユーザースレッドがすべて終了すると、デーモンスレッドの処理中であってもJVMが即座に終了するという点です。つまり、デーモンスレッドの唯一の目的はユーザースレッドを支援することにあり、単独ではプログラムの実行を維持できません。isDaemon()メソッドの役割isDaemon()メソッドを使用すると、あるスレッドがデーモンスレッドかどうかを判定できます。戻り値はboo

  2. Java 8におけるインターフェースの機能強化 〜デフォルトメソッドと静的メソッド〜

    Java 8で導入されたインターフェースの新機能Java 8では、インターフェースに「デフォルトメソッド(default method)」という新しい概念が導入されました。この機能は後方互換性(下位互換性)を維持するために追加されたもので、既存のインターフェースを壊すことなく、Java 8の強力なラムダ式の恩恵を受けられるようにすることを目的としています。なぜデフォルトメソッドが必要だったのか例えば、従来のListやCollectionインターフェースにはforEachメソッドの宣言が存在しませんでした。ここで単純にforEachメソッドをインターフェースへ追加すると、これらのインターフェース