This discussion is archived
1 2 Previous Next 22 Replies Latest reply: Oct 27, 2009 12:47 PM by 3004 RSS

Notify() method

843789 Newbie
Currently Being Moderated
Hi Java Programmers:

I'm having a little problem here...

Well, I want to "wake up" a thread that is waiting (used the method wait() )...
but I already tryed a lot of things, searched a lot, and I can't get it to work...

Here is the code:
try {
            while (!str.equalsIgnoreCase("endchat")) {
                str = in.readLine();
                String datetimestring = (Calendar.getInstance()).getTime().toString();
                if(str.equalsIgnoreCase("endchat"))
                    str = "RX Terminating Chat...\n   Closing Connection!";
                data = "\nThread ID: " + Thread.currentThread().getName() + "\nReceived Message @ " + datetimestring + ":\n'" + str + "'";
                if (!cache.push(data))
                    System.err.println("TX WARNING!   Too much data to process...\n   You may have lost some information!");
                else reader.notify();
            }
        } catch (IOException ex) {
            System.out.println("TX ERROR: Cannot read input!\n   " + ex);
            System.exit(1);
        }
else reader.notify();
reader is a Thread.


Code where I've put the wait();
    public synchronized void run() {
        while(true) {
            while(inCom.hasNext()) {
                System.out.println(inCom.read());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    System.err.println("blabla");
                }
            }
            try {
                wait();
            } catch (InterruptedException ex) {
                System.err.println("blabla");
            }
        }
    }
Many Thanks in advance!
Freiheitpt
  • 1. Re: Notify() method
    3004 Newbie
    Currently Being Moderated
    Define "doesn't work."

    If you call notify, then exactly one thread waiting on that object will be awakened (assuming there is at least one waiting thread). You cannot predict or control which thread--unless of course there is only one thread waiting on that object. If you call notifyAll, then all threads will be awakened.

    The awakened threads will get CPU cycles eventually, but you cannot predict or control when.

    If you happen to call notify or notifyAll before the other thread calls wait, then the waiting thread will not receive the notification.
  • 2. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    I've already debugged the program.

    the thread is waiting for a notify and no other threads have wait() nor are waiting.
    i have already tryed notifyAll() and notify()

    what I have there: reader.notify(),
    was one of the last efforts to make it work.
  • 3. Re: Notify() method
    DrClap Expert
    Currently Being Moderated
    Those two "synchronized" blocks: are they synchronizing on the same object?
  • 4. Re: Notify() method
    3004 Newbie
    Currently Being Moderated
    What I said still holds. And you still haven't made clear just what the problem is. I'm guessing that it's that your waiting thread is never waking up, or appears not to be.

    So, at least one of the following is true:

    - The waiting thread doesn't call wait until after the other thread calls notify.

    - The waiting thread is waiting on one object, but the notify thread is calling notify on another.

    - Your debugging/observations are faulty, and you're not seeing what you think you're seeing, or you're making bogus assumptions about the implications of what you are seeing.

    - You are not running the code that you think you are.

    - There are gremlins in your system.

    - You are the lucky square-root-of-negative-pi-th downloader of the JDK, and as such, you got this special easter egg that leads to special behavior that nobody else can see.
  • 5. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    Freiheitpt wrote:
    I've already debugged the program.

    the thread is waiting for a notify and no other threads have wait() nor are waiting.
    i have already tryed notifyAll() and notify()

    what I have there: reader.notify(),
    was one of the last efforts to make it work.
    Reader is a thread, but is "this" when used from your run() method? In other words, is your run() method overriding Runnable.run(), or Thread.run()? If it's overriding Runnable, than it's the runnable object that is being waited on, not the Thread. And therefore calling reader.notify() will not be operating on the same object.

    Also, are you synchronizing on reader before attempting notify?

    You can get around this by using a dedicated lock object and doing wait/notify on that:
    Object condition = new Object();
    
    //...
    synchronized(condition) {
       condition.wait();
    }
    
    //elsewhere...
    synchronized(condition) {
       condition.notify();
    }
    It's not generally a good idea to call wait/notify on a Thread object.

    Edited by: endasil on 27-Oct-2009 3:30 PM
  • 6. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    I only have 1 syncronized block, is the one that you see there in the code I've posted =)
  • 7. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    Freiheitpt wrote:
    I only have 1 syncronized block, is the one that you see there in the code I've posted =)
    Then I'd suggest reading the Javadoc for Object.wait() and Object.notify().

    Especially the parts that say clearly that you need to own the object's monitor before calling wait/notify on that object.
  • 8. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    >
    your run() method overriding Runnable.run(),
    >


    yes, i'm overriding run from runnable
  • 9. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    Freiheitpt wrote:
    >
    your run() method overriding Runnable.run(),
    >


    yes, i'm overriding run from runnable
    Then there's your second problem. You're not using the same object for wait() as you are for notify().
  • 10. Re: Notify() method
    3004 Newbie
    Currently Being Moderated
    Freiheitpt wrote:
    I only have 1 syncronized block, is the one that you see there in the code I've posted =)
    You have at least two--one for wait and one for notify.

    Or else you're calling wait and notify inside the same sync block.

    Or else you are getting IllegalMonitorStateException (I forget the exact name).

    Or else you are never calling wait or never calling notify.

    (Note that a synchronized method is just a special case of a synchronized block.)

    Regardless of how many sync blocks you have, the question (or one of the questions anyway) is: are you calling wait and notify on the same object? You can have only one sync block but a million different objects with that same method. When you call X.notify(), X has to point to the same object that Y pointed to when you called Y.wait().
  • 11. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    >
    The waiting thread is waiting on one object, but the notify thread is calling notify on another.
    >

    Maybe.
    but i wrote wait() on the run() of the object, wich i'm trying to notify
    hmmm
  • 12. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    >
    else you are getting IllegalMonitorStateException
    >

    yes
  • 13. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    Freiheitpt wrote:
    >
    The waiting thread is waiting on one object, but the notify thread is calling notify on another.
    >

    Maybe.
    but i wrote wait() on the run() of the object, wich i'm trying to notify
    hmmm
    When you subclass Runnable and override the run() method, "this" in that context is the Runnable, not the thread. A Thread, if created properly, has a run() method that delegates to a separate object of type Runnable, which contains the actual run() method. Therefore, the Thread object is NOT the same as the Runnable object. Now, you have both admitted that reader is a Thread, and that you have not overriden Thread.run(), so there is no question--you are operating on two separate objects.

    Get around this and avoid it in the future by using an explicit lock object as I said in my first post.
  • 14. Re: Notify() method
    843789 Newbie
    Currently Being Moderated
    Freiheitpt wrote:
    >
    else you are getting IllegalMonitorStateException
    >

    yes
    Oh WTF dude you don't think that's relevant information to share from the start? Stop wasting our time and take some initiative in providing relevant information.
1 2 Previous Next