【Java】wait・notifyを使ってスレッド間の待ち合わせを実装する
  • facebookページ
  • twitterページ
  • 2021.03.19

    【Java】wait・notifyを使ってスレッド間の待ち合わせを実装する

    マルチスレッド処理において、「A」の処理が完了するまで「B」の処理を待ち合わせるといったケースがあります。これを「スレッド間の待ち合わせ」と言い、並列で動作するスレッドを制御する上で重要な知識となります。

    この記事では、Javaの wait, notify, notifyAllメソッドを使用して、マルチスレッド処理における待ち合わせを制御をする方法を解説します。

    スレッド間の待ち合わせをする3つのメソッド

    Javaでは、すべてのクラスのベースとなる Objectクラスに、スレッド間の待ち合わせ制御で使用する3つのメソッドが用意されています。

    wait メソッド

    waitメソッドは、別のスレッドから notifyまたは notifyAllメソッドが呼び出されるまで、スレッドを一時停止するメソッドです。

    notify / notifyAll メソッド

    notifyおよび notifyAllは、 waitで一時停止させておいたスレッドを再開させるためのメソッドです。

    notifyは、ウェイトセットにあるスレッド1つを再開させるメソッドで、複数のスレッドが waitで待機している状況では、再開するスレッドはJVMによってランダムに選択されます。

    notifyAllは、 waitで一時停止しているスレッドを全て再開するメソッドです。

    ポテパンダの一言メモ

    waitnotifyおよび notifyAllメソッドを実行する場合は、 synchronizedを使って、該当のオブジェクトのロックを取得しておく必要があります。

    「wait」メソッドの使い方

    最初は、 waitメソッドの使い方を見ていきましょう。 waitメソッドは、現在のスレッドを一時停止し、該当のオブジェクトに対し notifyおよび notifyAllメソッドが呼ばれるまで待機します。

    synchronizedをメソッドに指定し、 waitメソッドの呼び出し前に該当のオブジェクトのロックを取得していることも忘れないようしましょう。

    また、スレッドに対する割り込みが入った時に InterruptedException例外が発生するため、これを catchなどで処理します。

    上のサンプルコードは、 thisのクラス・インスタンスに対する waitメソッドの呼び出しですが、オブジェクトを指定して waitメソッドを呼び出す場合は、 synchronizedブロックで該当オブジェクトのロックを取得後、 waitを呼び出します。

    タイムアウトを指定する

    waitメソッドの引数にタイムアウト時間を指定すると、指定した時間まではスレッドを一時停止し、タイムアウト時間を過ぎても notifyまたは notifyAllが呼び出されない場合は、スレッドを再開させます。

    「notify」メソッドの使い方

    次は、 waitでウェイトセットに入っているスレッドを再開させる notifyメソッドの使い方を見ていきましょう。

    waitメソッドを読んだスレッドはブロックされるため、別のスレッドを生成して notifyメソッド呼び出します。また synchronizedを指定して notifyで再開させるオブジェクトのロックを獲得するのも忘れないようにしましょう。

    ポテパンダの一言メモ

    notifyでは InterruptedException例外をキャッチする必要はありません。

    「notifyAll」メソッドの使い方

    notifyAllnotifyと同様です。
    synchronizedで再開させるオブジェクトのロックを獲得してからメソッドの呼び出しを行います。

    wait / notifyを組み合わせて待ち合わせを実装

    各メソッドの使用方法を確認したところで、 waitnotifyを使ってスレッドの待ち合わせを実装するサンプルコードを見ていきましょう。

    上のコードを実行すると次のような結果となります。

    まとめ

    Javaの waitnotifyおよび notifyAllメソッドで、スレッド間の待ち合わせを実装する方法を解説してきました。

    マルチスレッド処理においては、同時並行で複数の処理が実行されるため、最初は理解や考え方が難しいですが、何本かのサンプルコードを実際に自分の手で組んでみれば自然と身につくはずですので、是非挑戦してみましょう。

    【関連記事】
    【初心者向け】Javaのスレッド(Thread)・マルチスレッドとは?使い方も紹介!



    優良フリーランス案件多数掲載中!
    フリーランスエンジニアの案件をお探しなら
    ポテパンフリーランス

    この記事をシェア

    • Facebookシェア
    • Twitterシェア
    • Hatenaシェア
    • Lineシェア
    pickup









    ABOUT US

    ポテパンはエンジニアと企業の最適なマッチングを追求する企業です。

    READ MORE