7 Replies Latest reply: Sep 17, 2007 11:09 AM by 807592 RSS

    Why wait() within synchronized context?

    807592
      why all the three methods�wait()/notify()/notifyAll()�must be called
      from within a synchronized context?
        • 1. Re: Why wait() within synchronized context?
          807592
          The purpose of the wait() method is to allow a thread to wait on a monitor. When someone else calls the notify() method on that monitor, the thread in question is awakened and proceeds to operate.

          Since the notify() method would, at the very least, have to access a list of those threads which are waiting on the monitor, it would need safe access to that list. To ensure that only one thread operates on the list (or whatever it is) in question, anyone adding to the list (by calling wait()) or taking from the list (by calling notify()) must own the synchronized context of that monitor.

          I think that's why, anyway. Does that help?
          • 2. Re: Why wait() within synchronized context?
            807592
            why all the three
            methods�wait()/notify()/notifyAll()�must be called
            from within a synchronized context?
            Because, to use them effectively, each must be associated with some kind of semaphore whose setting tells the waiting thread whether it can or can't proceed. To produce reliable code this semaphore must be protected by synchronization when changed or tested. For example, a tyical use might be:
            synchronized (queue) {
                 while(queue.isEmpty())
                    queue.wait();
                 item = queue.pop();
                 }
            If this code wasn't protected by synchronization then another thread might, for example, add an item to the queue between the while test and the wait, resulting in the thread waiting even though the queue was not empty, or another thread might swipe the item between the wait and the pop.

            Basically, I think it's fair to say, if a wait or a notify is on it's own in the synchronized block then you aren't using it properly.

            And, something that confused me, when a thread exits wait it goes back into the synchronized state (if necessary, delaying until the monitor is free).
            • 3. Re: Why wait() within synchronized context?
              807592
              Basically, I think it's fair to say, if a wait or a
              notify is on it's own in the synchronized block then
              you aren't using it properly.
              I don't know if I agree with that. Some time ago, I implemented a synchronized queue and it looked roughly like this:
              public synchronized void enqueue(T obj) {
                  // do addition to internal list and then...
                  this.notify();
              }
              // blocking dequeue method
              public synchronized T dequeue() {
                  while (this.size()==0) {
                      this.wait(); // this was accompanied by a try-catch block, but you get the idea
                  }
                  return // something from the queue
              }
              The actual implementation had a method which permitted the caller to unblock all waiting threads, having them throw an exception... but you get the idea. Isn't that appropriate?
              • 4. Re: Why wait() within synchronized context?
                796440
                Isn't that appropriate?
                Yes, IMAO.
                • 5. Re: Why wait() within synchronized context?
                  807592
                  I don't see any waits or nofies on their own in a synchronized block in your example. The wait's synchronize includes the test and the notify's includes the

                  //do addition.

                  That's fine. What I'm saying is where you see code like
                   synchronized(this) {
                        wait();
                       }
                  Where the programmer has just put in the synchronized to avoid the IllegalMonitorStateException, Then it's not a good sign.
                  • 6. Re: Why wait() within synchronized context?
                    807592
                    Oh, good point. Sorry... somehow I'd read your post to say that you should have both a "wait" and a "notify" in each and every synchronized block. Not sure how I did that. Sorry. :)
                    • 7. Re: Why wait() within synchronized context?
                      807592
                      wait () must be within the synchronized context in order to allow a thread to wait untill the notify method is called .