• Post Reply Bookmark Topic Watch Topic
  • New Topic

wait() & notify() - why do they need to possess a lock  RSS feed

 
Adrian Sosialuk
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone,

A newbie question: why when I invoke methods wait() and notify()
I need to have an object's lock ? Could someone please explain me
giving some example why it would be not a good idea to let one do that ?
For me, it looks like an object has some kind of queue and when
somebody calls wait(), that thread is added to that object's queue
and waits to be notified by it. And honestly, I have no idea, why
it should possess that objects lock in order to do that ... :/

Thanks a lot,

Adrian
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This topic recently came up in this thread. Here is a relevant post from me:
the basic intent of wait() is that you want a thread to wait for some event. What that event is, it's up to you to code. You wait for a notify(), at the very least, but for various reasons it's not enough to just wait for notify. A notify is like a tap on the shoulder saying "something happened". But you need to check after the notify - what happened, and was it the thing you were waiting for? Maybe you were waiting for a boolean variable to turn true, or for an int value to reach 0, or any number of other possible things you might imagine.

What these things have in common is: they all involve changes in some data, somewhere, and that data is being manipulated or accessed by more than one thread. And any time you have changeable data accessed by more than one thread, you need some sort of protection in order to make it safe - by using synchronization, transient, or java.util.concurrent.locks classes.

Back when they originally designed wait(), transient wasn't very effective, and java.util.concurrent wasn't around. So they chose to give programmers some extra encouragement to do what they really should have been doing anyway: use synchronization to protect the integrity of the data being accessed. It's a form of extra run-time checking to catch a common source of errors.

And from Henry:
I would like to address the question of "why" a bit more...

First, this is *not* a Java issue -- the designers of Java didn't just invent the wait/notify mechanism. If you examine the condition variable support of the Solaris threads library, POSIX threads library, or even Windows threads library, the all require that a mutex (lock/monitor) be held during the waiting call, and they all will release and reacquire the lock during the call.

Why? it is because every single other threading library does it.


As for why all thread libraries does it, Jim explained most of it. It is because the condition variable is signalling a condition, that is tied to a state variable, that must be shared between threads. To further elaborate, it is also that it can't be done outside of the wait() method -- there is a really subtle race condition.

In the simple case, let's have one thread wait for all notifications. This thread grabs the lock, does some work, and goes back to a waiting state. If for example, the CV didn't require the mutex, but the thread must wakeup, grab the lock, do the work, release the lock, and then go back to a wait state. It will be possible for a second notification to be sent, in between the wakeup, and the lock grab -- hence, a notification will be lost.

Condition Variables not only release and reacquire locks, they also go into and out of the cooresponding wait state, in an atomic fashion, so that notifications will not be lost. (It is still possible to lose notification if the locks are released manually, via leaving a block, but not if all releases and reacquires are done with wait()). This is why the wait() mechanism must own the lock -- because it will not be possible for an additional method call to release the lock atomically.


As for notify, there is no reason for that. In fact, I am not sure if any of the other threading libraries require it. I guess Java does it to be consistent.


BTW, for the purpose of this post, I am using lock, mutex, and monitor, interchangeably.
 
Adrian Sosialuk
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jim,

Thanks for your quick and very accurate answer
I must admit that this is the only forum where I can
count on a detailed answer without any fuss ...
I'm still learning java and having posted to sun's
forum I very often got some only "mystery" links
back as the answer which didn't explain a lot :/

One more time - thanks a lot !

Adrian
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, you lucked out because we happened to have just talked about it, so I knew exactly where it was. And normally I'd have just linked to the thread - but since I knew that thread mixed in numerous other issues, I thought it would be better to just extract the relevant bits. Copy and paste worked quite well in this case.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!