views:

66

answers:

2
  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: 

There are a couple of problems with this code. I suspect you're 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 Thread.sleep() method will suspend the current thread for the specified interval. Object.wait() is something else entirely and it's unlikely that that's what you want.

You can see how I've eliminated the thread t. If you really want to create a separate thread and have the printouts produced on that thread then you need to give the thread something to do. The easiest way to do that is to override the thread's run() method and have the thread 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 in fact creating a thread with no thread body, so when you call t.start() the empty thread would simply start up in the background and then immediately die.

Note that I had to add a try/catch clause for InterruptedException now that the sleep call has migrated to inside the thread. run() isn't 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 of the work in the thread t and the rest of the work in your main thread. Here's an example of how you could split apart the work into two threads:

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 this calls t.join() it will wait for the thread to finish executing, which will take 10 seconds since it's sleeping. Once the thread is finished then the join() method will return and allow the main thread to continue. The end result will appear the same to the user: the program will print X, pause for 10 seconds, and then print Y.

John Kugelman
+1  A: 

Well, John's suggestions will do the thing. But you might still feel blur regarding the exception occurred. For that I would like you to read the documentation of Object.wait() method, and of IllegalMonitorStateException.

After reading those, a question might come to your mind that, what the hell is Object's monitor. So here it is from wikibooks,

Each object has an 'Object monitor'. Basically it is a 'semaphore', indicating if a critical section code is being executed by a thread or not. Before a critical section can be executed, the Thread must obtain an 'Object monitor'. Only one Thread at a time can own that object's monitor.

Adeel Ansari