0

Am I not using synchronization properly:

In following code i am having 2 problems :
1. while makingmethods (designBusiness,createBusiness,sellBusiness) as synchronized like in this case, a call to wait() says IllegalMonitorStateException but i can not understand why? because in designBusiness method Designer Thread do get a lock so it is supposed to wait on wait call. I am getting IllegalMonitorStateException on wait() and notify() both.


2.Even though when i remove synchronized keyword and use synchronized(this) block for particularly wait() and notify() still i got DEADLOCK! WHY?

public class Main {
  HashMap<String, Integer> map = new shop().orderBook();

  public static void main(String[] args) throws InterruptedException {

    Main main = new Main();

    main.sellBusiness();
    Thread.sleep(3000);
    main.designBusiness();
    Thread.sleep(3000);
    main.createBusiness();
  }

  private synchronized void designBusiness() throws InterruptedException {

    Thread designThread = new Thread(new Runnable() {
      public void run() {
        Set set = map.keySet();
        System.out.println("Tracking OrderList");
        System.out.println(set.size());
        try {

          System.out.println("waiting.........");
          wait();
          System.out.println("wait completed");

          System.out.println("after design process items in orderList are "
              + map.keySet().size());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }

    }, "Designer Thread");
    designThread.start();
    System.out
    .println("status of Designer Thread" + designThread.isAlive());
  }

  private synchronized void createBusiness() throws InterruptedException {
    Thread createThread = new Thread(new Runnable() {

      public void run() {
        System.out.println(Thread.currentThread().getName()
            + " started");
        Creator creator = new Creator();
        creator.create(map);
        notifyAll();
        System.out.println("notified");

      }
    }, "Creator Thread");
    createThread.start();
    createThread.join();
    System.out.println("status of Creator Thread" + createThread.isAlive());
  }

  private void sellBusiness() throws InterruptedException {
    Thread sellThread = new Thread(new Runnable() {
      public void run() {
        Seller seller = new Seller();
        seller.sellGold(45000, 15);
        seller.sellSilver(14000, 60);
        seller.noteOrder("Mrs Johnson", 15000, map);
        seller.noteOrder("Mr. Sharma", 10000, map);
        seller.sellGold(60000, 20);
        seller.noteOrder("Mr. Hooda", 17500, map);
        System.out.println(Thread.currentThread().getName()
            + " done selling");
      }
    }, "Seller Thread");
    sellThread.start();
    sellThread.join();
    System.out.println("status of seller Thread" + sellThread.isAlive());
  }
}

please help i could not find any solution for this problem and i am searching from last night.

2
  • DEADLOCK? Which threads get locked? main and designer and creator? Commented Jul 8, 2013 at 11:39
  • @johnchen902 deadlock due to designer and creator. i don't think is was the reason. Commented Jul 8, 2013 at 12:53

4 Answers 4

2

If you got this exception you are not in a block or method that is synchronised on the object you are waiting on. That is the meaning of the exception. The only meaning.

The wait() method you are calling is executed on the instance of the anonymous inner class you are creating. The synchronised method you are creating it from is synchronised on a different object, and it has probably also already executed by the time the inner object gets to the wait() call.

You need to sort out which object is which here. Probably you need to call Main.this.wait(), but it depends on what you think you're trying to do, which isn't clear from your question.

NB you aren't getting a deadlock, you are getting an infinite block. It isn't the same thing.

0
1

wait(), notify() and notifyAll() must be used with synchronized. What I would do is trying to solve the deadlock.


To illustrate why you got deadlock (unrelated code removed) (if I guessed right):

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Main main = new Main();
        main.createBusiness();
    }
    private synchronized void createBusiness() throws InterruptedException {
//          ^^^^^^^^^^^^ got lock
        Thread createThread = new Thread(new Runnable() {
            public void run() {
                synchronized (Main.this) {
//              ^^^^^^^^^^^^^^^^^^^^^^^^ try to get lock --> DEADLOCK
                    Main.this.notifyAll();
                }
            }
        });
        createThread.start();
        createThread.join();
//      ^^^^^^^^^^^^^^^^^^^ wait for createThread to die --> DEADLOCK
    }
}
  1. Main thread got the lock of Main.this.
  2. createThread tried to get lock of Main.this, but it's locked by Main.this, hence waiting.
  3. Main thread waited for createThread to die, hence waiting. (2 and 3 can be swapped)

Since I'm not sure what you tried to achieve, I'm not sure if the following is the right solution, but you can try (even if the above guessed wrong):

First, create a lock object.

public class Test {
    private Object lock = new Object();

Second, in designer thread

synchronized (lock) {
    lock.wait();
}

Third, in creator thread

synchronized (lock) {
    lock.notifyAll();
}
0

wait() must be executed from synchronized block on the same monitor. Since wait() is the same as this.wait() you have to wrap it with synchronized(this):

synchronized(this) {
    wait();
}
1
  • you may not understand my question. 1. i am using synchronized method so no need to synchronize(this), i guess. 2. even when i use synchronized(this) i get DEADLOCK. Commented Jul 8, 2013 at 11:19
0

If you try to unlock an onject by a threas which is not locked by that thread then you may end up with the same error.

Not the answer you're looking for? Browse other questions tagged or ask your own question.