Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2007

Tip: Looking for answers? Try searching our database.

Understanding java.lang.Object.wait()

Thread view: 
Aria - 27 Jun 2007 03:01 GMT
Hi,

I am a bit confused as how wait() actually works. I know the purpose
of this method but what I wanted to know is when a few threads waiting
on a certain object lock and they are signaled via notifyAll(), how
does one of the threads on the waiting list for that object lock gets
the lock and what would happen to the other threads? Let me elaborate
my confusion in the following simple example:

Thread1, Thread2, Thread3 they all waiting on "obj" that is being
processed by Thread4. Thread4 runs as following:

public void run() {

 synchronized (obj) {
   try {
     // do some processing on obj status
     obj.notifyAll()
   } catch (InterruptedException ie) { }
 }
}

Now, I understand that notifyAll() ONLY notifies other threads
blocking on this object that the current thread is done with the
object is "ready" to release the lock. That is the actual release of
the lock occurs AFTER the code is out of synchronized block.

Having said that, what exactly happens when the waiting threads
receive such notification? That is:

// Other threads running block
public void run() {
 synchronized (obj) {
   while (some condition not being met) {
     try {
       obj.wait();
       // (1)
     } catch (InterruptedException ie) { }
     // Some code to process
   }
 }

}

When "ALL THE THREADS" receive such signal, do they all "get out" of
wait() method and then whoever wins the contention would gets the lock
and the rest are put on the waiting list once they "failed" the
condition? Or ONLY a thread that gets the lock is allowed to finish
its wait() and continue on with execution? What I want to know is does
JVM even allow the threads to get out of wait() before actually
acquiring the lock?

Unfortunately the wait() method is implemented in a native code so I
can't figure out the inner work of this method from the source code.

Thank You
bencoe@gmail.com - 27 Jun 2007 04:46 GMT
> Hi,
>
[quoted text clipped - 53 lines]
>
> Thank You

If you have a blocking object that a few threads are waiting on, when
you use notifyAll, I'm pretty sure that the next object waiting would
get a lock, and that any other sleeping threads would continue waiting
until that one is done and so on... I usually explicitly use
semaphores when I'm doing threading, someone please correct me if I'm
wrong.

Ben.
Owen Jacobson - 27 Jun 2007 06:21 GMT
> Hi,
>
[quoted text clipped - 3 lines]
> does one of the threads on the waiting list for that object lock gets
> the lock and what would happen to the other threads?

The other threads wait for the first thread to release the lock, and
then one of them wins it.  This repeats until all of the threads have
been resumed, exactly like any other lock contention scenario.

> Now, I understand that notifyAll() ONLY notifies other threads
> blocking on this object that the current thread is done with the
[quoted text clipped - 22 lines]
> and the rest are put on the waiting list once they "failed" the
> condition?

It's a little hard to interpret this, but it sounds right.

When you call notifyAll on an object, every thread that's wait()ing on
that object resumes and tries to reaquire the monitors they held,
blocking if necessary until another thread releases those monitors.
The contract for a monitor is that at most one thread can hold it at a
time; this is enforced by the JVM.

If several threads that held the same monitor are awoken at the same
time, they will run "one at a time" through the parts of their
executions that hold that monitor.  None of them will be put back to
waiting on the object.

Owen
Aria - 27 Jun 2007 14:45 GMT
> > Hi,
>
[quoted text clipped - 49 lines]
>
> Owen

So according to your statement, every time blocking threads are
signaled, ALL of them gets out of obj.wait(), "try" to acquire the
lock on the object, and only one would prevail. Which brings us to the
question I asked, they ALL get to their line (1) after each
notification and only put on the waiting list due to the while
(condition not being met). Is that a correct interpretation?

If that is the case, this would be a bit of waste of effort on JVM
part because this concludes that after each notification, JVM needs to
move all the blocking threads out of the waiting list, choose one as
the winner, let the rest go through their while loop and put on the
waiting list again. couldn't the scheduler select one thread, give it
a lock and "keep" the rest on the waiting list without getting them
ALL out of wait()?

So my question pretty much boils down to this: When a notification
occurs, do ALL waiting threads execute line [b](1)[/b] regardless of
whether win the contention and only to be put back on the waiting list
after failing the while (condition not being met)?
Eric Sosman - 27 Jun 2007 15:14 GMT
>>> Hi,
>>> I am a bit confused as how wait() actually works. I know the purpose
[quoted text clipped - 57 lines]
> a lock and "keep" the rest on the waiting list without getting them
> ALL out of wait()?

    It's not the JVM's fault that you called notifyAll()
if notify() would have sufficed ...

> So my question pretty much boils down to this: When a notification
> occurs, do ALL waiting threads execute line [b](1)[/b] regardless of
> whether win the contention and only to be put back on the waiting list
> after failing the while (condition not being met)?

    If you use notifyAll(), then all the threads that are
in wait() on that obj will awaken and will compete for obj's
lock.  There may also be other threads that are not in wait()
but are competing for that same lock.  Assuming the current
holder of the lock eventually releases it, some other thread
will acquire it.  There's no telling which of the competing
threads might win; it might even be a Johnny-come-lately that
was neither waiting nor blocked at the moment of notifyAll(),
but just happened along at a fortuitous instant.

    Anyhow, some thread will acquire the lock and will do
whatever it does.  If it's in the synchronized block above,
it will either dive back into obj.wait() or it will find
the condition satisfied and exit the while loop and then
the synchronized block.  Either way, it releases obj's lock,
and then all the threads that still want the lock start
jumping up and down, waving their hands in the air, and
shouting "Me! Me! Pick me!" until one of them (or yet another
Johnny-come-lately) gets it.  And so on, and so on, until
everybody has either gone back into obj.wait() or left the
block and gone on to do something else.

    If you use notify() instead of notifyAll() the scenario
is pretty much the same, except that only one thread will
be awakened from obj.wait() (or zero, if no thread is waiting).
You still have the Johnny-come-latelies and so on, which is why
the awakened thread must re-test its predicate: the awakening
tells the thread that somebody thought something interesting
*might* have happened (which may turn out to be wrong if the
thread is waiting for a compound condition), and even if the
interesting thing *was* true for a moment it may have ceased to
be true by the time the awakened thread re-acquires the lock.

Signature

Eric Sosman
esosman@acm-dot-org.invalid

Michael Jung - 27 Jun 2007 19:43 GMT
> > > Now, I understand that notifyAll() ONLY notifies other threads
> > > blocking on this object that the current thread is done with the
[quoted text clipped - 19 lines]
> > > and the rest are put on the waiting list once they "failed" the
> > > condition?

No, they come out of the wait, but halt at the next statement (1), because
they do not have the lock. They don't get to "condition" yet.

> > It's a little hard to interpret this, but it sounds right.
> > When you call notifyAll on an object, every thread that's wait()ing on
[quoted text clipped - 6 lines]
> > executions that hold that monitor.  None of them will be put back to
> > waiting on the object.

But since they are all in a synchronized block, only one can run - the one who
owns the monitor.

> So according to your statement, every time blocking threads are
> signaled, ALL of them gets out of obj.wait(), "try" to acquire the
> lock on the object, and only one would prevail. Which brings us to the
> question I asked, they ALL get to their line (1) after each
> notification and only put on the waiting list due to the while
> (condition not being met). Is that a correct interpretation?

No. As above, they do not wait because they do another while-iteration, but
because they are in a synchronized block and wait for the lock immediately
after the wait.

[...]
> So my question pretty much boils down to this: When a notification
> occurs, do ALL waiting threads execute line [b](1)[/b] regardless of
> whether win the contention and only to be put back on the waiting list
> after failing the while (condition not being met)?

No. Only one executes it. Why don't you write a simple test program?

   public static void main(String[] argv) {
       final Object o = new Object();
       Thread t1 = new Thread() {
               public void run() {
                   synchronized (o) {
                       try {
                           o.wait();
                           System.out.println(this);
                           Thread.sleep(1000);
                       }
                       catch (InterruptedException e) {
                       }
                   }
               }
           };
       t1.start();
       Thread t2 = ... // as t1
       Thread t3 = new Thread() {
               public void run() {
                   synchronized (o) {
                       o.notifyAll();
                   }
               }
           };
       t3.start();
   }

You will see the prints come in 1s separated, your interpretation would expect
them to show up immediately.

Michael
Aria - 27 Jun 2007 20:29 GMT
Thank you guys, actually I wrote a small program to verify my
statements and along the way I learned some else too. But for some
reason the last time I posted it, it did not go through. *shrug* Again
thank you.
Roedy Green - 28 Jun 2007 21:42 GMT
>Having said that, what exactly happens when the waiting threads
>receive such notification? That is:

this will likely be native code.  I would guess all that happens is a
bit meaning "ready to run" or "almost ready to run"  gets set in the
notified thread control blocks, and perhaps they get moved to a
different queue than where there are now on a waiting queue.

Sun will let you look at the source code of the JVM.  Perhaps you sort
out the details from that.

The code for notifyAll might be able to suppress being interrupted to
run a different thread.  It might get interrupted by IO or unrelated
programs, but no other thread in the JVM can get control.
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.