HOWTO · Java

Java で wait() メソッドと notify() メソッドを使用する

このチュートリアルでは、Java の wait() メソッドと notify() メソッドについて説明します。

このチュートリアルでは、Java の wait() および notify() メソッドについて説明します。

Java で wait() および notify() メソッドを使用する

wait() および notify() メソッドは、特定の条件が満たされるまでスレッドを待機させるメカニズムを提供します。 たとえば、要素の固定サイズのバッキング ストアに対してブロッキング キューの実装を記述したい場合などです。

wait()notify() は Java の保護されたブロックで使用され、複数のスレッドのアクションを調整します。 wait() メソッドはスレッドを一時停止するために使用され、notify() メソッドはスレッドを起動するために使用されます。

wait() メソッド

wait() メソッドは、他のスレッドが完了するか、同じオブジェクトで notify() または notifyAll() メソッドを呼び出すまで、現在のスレッドを強制的に待機させます。 wait() メソッドは、次のさまざまな方法で使用できます。

  1. wait() の使用:

    これは、他のスレッドが notify() または notifyAll() メソッドを呼び出すまで、現在のスレッドを無期限に待機させる wait() メソッドの単純な呼び出しです。

  2. wait(長いタイムアウト) を使用:

    この wait() メソッドの呼び出しにより、タイムアウトを指定できます。その後、スレッドは自動的に起動されます。timeout は長い時間の値です。

    notify() および notifyAll() メソッドを使用して、タイムアウト前にスレッドを起動することもできます。 timeout パラメータに値 0 を設定すると、wait() 呼び出しと同様に機能します。

  3. wait(long timeout, int nanos) を使用:

    この呼び出しも、wait(long timeout) と同様に機能します。 唯一の違いは、より高い精度を提供できることです。

    タイムアウト期間は、1_000_000*タイムアウト + ナノ秒としてナノ秒単位で計算されます。

notify() および notifyAll() メソッド

notify() 機能は、オブジェクト モニターへのアクセスを待機しているスレッドを起動するために使用されます。 notify() 機能は 2つの方法で使用できます。

  1. notify() を使用する:

    待機中のすべてのスレッドに対して、notify() メソッドは、特定の 1つのスレッドのみを起動するように通知します。 ウェイクアップするスレッドの選択は決定論的ではなく、実装によって異なります。

    notify() は 1つのスレッドしか起動できないため、複数のスレッドを起動したい場合には役に立たないかもしれません。

  2. notifyAll() の使用:

    notifyAll() は、オブジェクト モニター上のすべてのスレッドを起動します。 スレッドが起動されると、他のスレッドと同様に通常の方法で完了します。

wait() メソッドを使用してスレッドをブロックし、notify() メソッドを使用してウェイクアップする例を試してみましょう。

package delftstack;

import java.util.LinkedList;
import java.util.Queue;

public class Example<T> {
  private Queue<T> Demo_Queue = new LinkedList<T>();
  private int Q_Capacity;

  public Example(int Q_Capacity) {
    this.Q_Capacity = Q_Capacity;
  }

  public synchronized void put(T Demo_Element) throws InterruptedException {
    while (Demo_Queue.size() == Q_Capacity) {
      wait();
    }

    Demo_Queue.add(Demo_Element);
    // Wake up the thread. notifyAll() can also be used for multiple threads
    notify();
  }

  public synchronized T take() throws InterruptedException {
    while (Demo_Queue.isEmpty()) {
      // Ask the thread to wait
      wait();
    }

    T item = Demo_Queue.remove();
    // Wake up the thread. notifyAll() can also be used for multiple threads
    notify();
    return item;
  }
}

上記のコードは、すべての wait() および notify() 呼び出しがコードの同期領域にあることを確認する必要がある単純なキュー ブロック操作を示しています。