1

I need some help to understand where my program is going wrong, I have a very simple program to learn about multithreading but every time I run the following code it gives me an IllegalStateMonitorException. I don't know what's causing this although I suspect it may be my synchronized block, Thanks.

Main Method class:

public class Lab8 {
    public static void main(String [] args) { 
        Thread1 thread1 = new Thread1(); 
        thread1.start();
    }
}

Thread 1:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Thread1 extends Thread {
public DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

public Thread1() { 
    super("Thread1");
}
public void run() { 
    Thread2 thread2 = new Thread2(); 
    System.out.println("==Start: " + dateFormat.format(new Date()) + "==\n"); 
    synchronized(thread2) { 
        try {
            this.wait();
        } catch (InterruptedException e) {
            System.err.println(e.toString()); 
        } 
        (new Thread(thread2)).start(); 
    }
    System.out.println("==End: " + dateFormat.format(new Date()) + "==\n"); 
}
}

Thread 2:

public class Thread2 implements Runnable {
@Override
public void run() {
    synchronized(this) { 
        for(int i = 1; i <= 100; i++) { 
            System.out.print(i + " ");
            if(i % 10 == 0) { 
                System.out.print("\n");
            }
        }
        notify(); 
    }
} 

}
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • If you get an exception, it is helpful to include the stack trace into your question. – Holger Jul 09 '15 at 18:44
  • Not just to include it here, but read it yourself. If you had read the stack trace, then you would not have had to "suspect it may be [in] my synchronized block:" You would have _known_ exactly what line of code threw the exception. – Solomon Slow Jul 09 '15 at 19:01

1 Answers1

2

You should understand, that the synchronized construct and the wait/notify mechanism are tied to an object instance. In your code, you are using

synchronized(thread2) { 
   …
        this.wait();

so the object of your synchronized statement and the one, you are calling wait on, are different. That causes the IllegalStateMonitorException. Note that waiting on the Thread1 instance while the other thread is calling notify() on its own Thread2 instance will not work as notify will wake up only threads waiting on the same instance.

Besides that, you should never synchronize on thread instances anyway. The reason is that the Thread implementation will synchronize on its own instance as well, so this might interfere. Further, you should not subclass Thread like you did with your Thread1 class but rather use composition like you did with your Thread2 class.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • Yeah, except, extending `Thread` is not actually _wrong_, it's just bad design. – Solomon Slow Jul 09 '15 at 19:02
  • @james large: Well, I said “should not” in the end notes, not meant to be a dogmatic rule, however, here it is the pattern that leads to accidentally synchronizing or waiting on a thread instance by just using `this`… – Holger Jul 09 '15 at 19:08