Why is this method throwing an IllegalMonitorStateException?

  public static synchronized void main(String[] args) throws InterruptedException {
    Thread t = new Thread();
    t.start();
    System.out.print("X");
    t.wait(10000);
    System.out.print("Y");
  }

      

  • What is the problem with this method?
  • How can I avoid such problems from now on?
+2


a source to share


2 answers


There are a couple of problems with this code. I suspect you are trying to write something like this:

public static synchronized void main(String[] args) throws InterruptedException {
  System.out.print("X");
  Thread.sleep(10000);
  System.out.print("Y");
}

      

The method Thread.sleep()

pauses the current thread for the specified interval. Object.wait()

is something completely different and it is unlikely that this is what you want.

You can see how I removed the stream t

. If you really want to create a separate thread and have printouts generated on that thread, you need to give that thread something to do. The easiest way to do this is to override the stream method run()

and specify the stream code there:

public static synchronized void main(String[] args) {
  Thread t = new Thread() {
    public void run() {
      System.out.print("X");
      try { Thread.sleep(10000); } catch (InterruptedException e) { }
      System.out.print("Y");
    }
  };

  t.start();
}

      



As written, your original code was actually creating a thread without a thread body, so when you call t.start()

, the empty thread just runs in the background and dies right away.

Note that I had to add a try / catch clause for InterruptedException

now that the sleep call has migrated inside the thread. run()

it is not allowed to throw exceptions, so now, unfortunately, we have to catch and ignore the exception.

Another way to write this would be to do some work on the thread t

and the rest of the work on the main thread. Here's an example of how you can split your work into two streams:

public static synchronized void main(String[] args) throws InterruptedException {
  Thread t = new Thread() {
    public void run() {
      System.out.print("X");
      try { Thread.sleep(10000); } catch (InterruptedException e) { }
    }
  };

  t.start();
  t.join();

  System.out.print("Y");
}

      

When it calls t.join()

, it will wait for the thread to finish executing, which will take 10 seconds after it hibernates. Once the thread is finished, the method join()

will return and continue to continue with the main thread. The end result is the same as for the user: the program will print X, pause for 10 seconds, and then print Y.

+2


a source


Okay, John's suggestions will do it. But you may still feel blurry about the exception that happened. For this, I would like you to read the documentation for Object.wait () and IllegalMonitorStateException .

After reading these questions, you might wonder what the hell is an object monitor. So here's from wikibooks .



Each object has an "Object Monitor". Basically it is a "semaphore" indicating whether the critical section code is being executed by a thread or not. Before the critical section can be executed, the thread must receive an "Object Monitor". Only one thread at a time can own this object monitor.

+1


a source







All Articles