Sunday, October 11, 2009

Why wait(),notify() and notifyAll() in the Object class?


Why wait(), notify() and notifyAll() methods have been defined in the Object class?

Java concurrency model uses locks to implement mutually exclusive access to objects in a multi-threaded environment and locks are associated with every object in Java (of type 'Object'), not only with Threads.


wait
, notify/notifyAll methods are used by threads to communicate with each other while trying to access a common object. Putting it differently, objects become a medium via which threads communicate with each other. For example: suppose there is a 'telephone' object, which at one point of time can be used by only one thread. Like every other object in Java, 'telephone' object would also have an intrinsic lock (monitor) associated with it which at one point of time can be acquired by only one thread. Suppose the 'telephone' object requires activation before it can be used and suppose only a few admin threads can activate the 'telephone' object.


As soon as a thread needs access to the 'telephone' object, it checks if the lock on that 'telephone' object is available or not, if yes, it acquires that and checks if the 'telephone' is active or not. If yes, it starts using it otherwise it calls 'wait()' on the telephone object which effectively releases the monitor of the 'telephone' object (eventually to be acquired by one of the admin threads for its activation) and puts the requester thread into the wait-set of the 'telephone' object. The requester thread goes into WAITING state. The way every object in Java has an intrinsic lock associated with it, it has an intrinsic wait-set associated with it as well.


Every other non-admin requester thread goes through the same process as discussed above till one of the admin threads acquire lock on the 'telephone' object and eventually activates it and subsequently calls 'notify()' or 'notifyAll()' on the 'telephone' object. 'notify()' will simply pick one of the threads from the wait-set of the 'telephone' object (which one will be picked is an implementation dependent stuff and Java Language specification doesn't enforce any restriction on which one to be picked) and the chosen thread will now get out of WAITING mode and start trying to acquire the monitor/lock of the 'telephone' object along with any other thread that might be vying to access the 'telephone' at that point of time.


The only difference between 'notify' and 'notifyAll' is that in case of the latter all the threads of the corresponding wait-set are picked and they all start trying to acquire the lock on the object (with any other incoming requester thread) at the same time.


Evidently you see that these three methods are essentially object-related and not thread-related and hence the designers of Java Language considered it wise to put them in the Object class instead of putting them into the Thread class. The usage of the 'object' (in our case 'telephone') is the particular object's prerogative and not that of the requester threads'. Putting these three methods in the Object class helps the objects owning/controlling their usage in a better way as in that case a thread needs to first acquire the lock on the object (kind of getting a license to use the object) and then calling either wait (in case the thread doesn't find the object in the state it would have wished it to be in and hence thought of waiting for some time to let the object become useful for it) or notify/notifyAll to alert other threads waiting on the object once it finishes using the object (of course in the case when the thread find the object useful in its current state).

Additionally, the communication among the interested threads becomes far too easier when the control is kept at the object's level - one common shared resource/medium and all interested threads communicating via it. Not that the communication won't be possible if these methods are kept in the Thread class, but the handling of the communication and usage of the objects in a multi-threaded environment will probably become more complex and less flexible in that case.

Liked the article? Subscribe to this blog for regular updates. Wanna follow it to tell the world that you enjoy GeekExplains? Please find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark


10 comments:

Thangarasu said...

Excellent Article. A way its demonstrated and example used is very clear.

Goutham said...

I have not understood about admin and non admin threads can you give a example

Geek said...

admin thread in the example explained in the above article means a thread which can activate the 'telephone' object and non-admin thread is the one which can't really use a 'telephone' object unless some admin thread has activated that object... does this help?

Goutham said...

Okay...Thanks.. I have read all your articles..continue the good work.

Atul said...

here's what I think why these methods defined in Object class..

you have two ways to create a new thread (extend Thread class or implement Runnable)

when you extend Thread class newly create Thread would have access to all the methods defined in the Thread class BUT when you implement Runnable interface you won't have access to the methods defined in Thread class in the new Thread. so where would be the best place to define wait,notify and notifyAll? Object class.

Goutham said...

@Atul

"you have two ways to create a new thread (extend Thread class or implement Runnable)"

but eigther way we are getting a Thread object right?

Gautam said...

good explanation for wait() notify() and notifyall(). But, it still is not clear why they are on the object class. Clearly, I have a reference of the thread, hence had these methods been in the thread class I could have easily invoked them . . .

ankit said...

Hey great article out of many i came across!!!

Javin Paul said...

Hi, Just to add while using wait and notify or notifyAll method in Java following things must be remember :

1) use notifyAll instead of notify if you expect more than one thread is waiting for lock.
2)wait() and notify() method must be called from synchronized context, see the link for more detailed explanation.
3) Always call wait() method in loop because if multiple threads are waiting for lock and one of them got lock and reset the condition and other thread needs to check the condition after they got wake up to see whether they need to wait again or can start processing.
4) use same object for calling wait() and notify() method, every object has its own lock so calling wait() on objectA and notify() on object B will not make any sense.

Mdhar said...

Hi geek, your way of explanation is very good. I like this point."wait, notify/notifyAll methods are used by threads to communicate with each other while trying to access a common object".

Thank you.