HOWTO · Java

Java.Lang.IllegalMonitorStateException

このチュートリアルでは、Java で java.lang.IllegalMonitorStateException を解決する方法を示します。

このページの内容

IllegalMonitorStateException は、マルチスレッド プログラミングに関連しています。 このチュートリアルでは、Java の IllegalMonitorStateException について説明し、実演します。

Java の java.lang.IllegalMonitorStateException

Java でマルチスレッド プログラミングを行うと、IllegalMonitorStateException が発生します。 モニターで同期しているときに、スレッドが待機しようとしたり、その時点でモニターを所有していない状態でモニターを待機している他のスレッドに通知したりすると、IllegalMonitorStateException が発生します。

synchronized ブロックにない object クラスからメソッド wait()notify()、または notifyAll() を呼び出すと、この例外がスローされます。 このシナリオの例を試してみましょう。

package delftstack;

class DemoClass implements Runnable {
  public void run() {
    try {
      // The wait method is called outside the synchronized block
      this.wait(100);
      System.out.println("Thread can successfully run.");
    } catch (InterruptedException ex) {
      ex.printStackTrace();
    }
  }
}

public class Example {
  public static void main(String[] args) {
    DemoClass DemoRunnable = new DemoClass();
    Thread DemoThread = new Thread(DemoRunnable);
    DemoThread.start();
  }
}

上記のコードは、Runnable クラスを実装するクラスを作成し、synchronized ブロックの外で wait メソッドを呼び出します。 ExampleDemoClass のインスタンスからスレッドを作成します。

wait メソッドは synchronized ブロックの外で呼び出され、スレッドは wait() メソッドを呼び出す前にモニターのロックを所有する必要があるため、IllegalMonitorStateException がスローされます。 出力を参照してください:

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread is not owner
    at java.base/java.lang.Object.wait(Native Method)
    at delftstack.DemoClass.run(Example.java:7)
    at java.base/java.lang.Thread.run(Thread.java:833)

この例外を修正するには、synchronized ブロックにある object ロックが取得された後で、wait()notify()、または notifyAll() メソッドを呼び出す必要があります。

wait() メソッドを synchronized ブロックに入れ、上記のコードにエラーがないようにしましょう。 例を参照してください:

package delftstack;

class DemoClass implements Runnable {
  public void run() {
    synchronized (this) {
      try {
        // The wait method is called outside the synchronized block
        this.wait(100);
        System.out.println("Thread can successfully run.");
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }
    }
  }
}

public class Example {
  public static void main(String[] args) {
    DemoClass DemoRunnable = new DemoClass();
    Thread DemoThread = new Thread(DemoRunnable);
    DemoThread.start();
  }
}

wait() メソッドが synchronized ブロック内にあり、オブジェクト モニターのロックが取得されると、コードは正常に実行されます。 出力を参照してください:

Thread can successfully run.