Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

wait()and notify()  RSS feed

 
badrinarayanan
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi friends,
what is the reason behind keeping wait() and notify() methods in the Object class rather than in Thread class?
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because both wait() and notify() are associated with the monitor lock that is part of the Object, not of the Thread. For example, notify() will only wake up those threads that are wait()ing on that same object's monitor lock.

- Peter
 
Yaroslav Chinskiy
Ranch Hand
Posts: 147
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Perfect example of use wait()/notify() is a queue.

One thread T1 is reading from the queue Q, the other thread T2 is writing to it. There are 2 ways to implement it. T1 can check the Q periodically for new objects and go to sleep (T1.wait(1000) for example) if the Q is empty. This design takes CPU time on unnecessary checks.

The solution is built in the Object class. You can set T1 to wait() on object Q for new data, and have thread T2 notify() that new data is written to the Q. For example.

public class Queue {

private List q = new ArrayList();

public void put(Object o) {
synchronized (q) {
q.add(o);
q.notify();

}
}

public Object get() {
Object o;
synchronized (q) {

while (q.isEmpty()) {
try {
q.wait();
} catch (InterruptedException ie) {
ie.printStackTrace();
return null;
}
}

o = q.remove(0);
}
return o;
}
}

When thread T1 tries to get() from empty Q, it will be put on the wait set of the Q object and release the lock. Once T2 adds object to the Q it calls notify() and releases the lock. Make sure to use wait() inside while loop since notifyAll() will wake up all threads on Q�s wait set and they will compete for the lock and data. So there is no guarantee the Q wont be empty after the awaken thread gets the synch lock. Also you must own the lock on an object before calling it�s wait()/notify()/notifyAll()

You can get more info in JLS chapter 17.

Hope that helps.
 
badrinarayanan
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks peter and Chinskiy...it was very helpful
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is my take on this question that many people wonder about:

1. Each object has a wait set. A wait set is a set of threads.

When a thread invokes wait() on an object, that thread is added to the object�s wait set. When a thread invokes notify(), some thread is removed from the object�s wait set.

Why does an object have a wait set?

2. Sometimes one thread does not want to execute a block of code until a certain condition exists. It wants to wait until the condition exists. Just at the moment the thread begins to wait, the condition changes. Alas, the thread misses the change and waits forever. To solve synchronization problems, Dijkstra invented semaphores and Hoare invented monitors.

Apparently, the Java designers decided to go with Hoare�s monitor. A monitor is a module with two operations, wait and signal, an internal state, and a number of condition variables (whatever those are). An object with a lock and a wait set looks rather like a monitor.

The more we can understand about semaphores and monitors, the better we will understand why objects are (like) monitors and therefore have methods wait and notify.

There is also another idea called conditional critical regions, an alternative to semaphores proposed by Brinch Hansen at about the same time as monitors. Michael Scott in Programming Language Pragmatics says Java might be said to be a blend of the features of monitors and conditional critical regions.

Further reading: Modern Operating Systems by Tanenbaum, then Foundations of Multithreaded, Parallel, and Distributed Programming by Andrews
[ June 04, 2004: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is another attempt to explain why wait and notify are methods of Object instead of Thread.

Suppose a thread does not want to execute a block of code until a certain condition exists. It wants to wait for the condition to exist. Then it wants to proceed.

So that thread calls wait(). At just the same moment, the condition changes. The thread needs to check the condition before being put into the wait queue.

How do we prevent the condition from changing while the thread is getting ready to wait? The thread locks the code that alters the condition. Then it waits. Then the virtual machine releases the lock.

The virtual machine puts the thread some place associated with the lock. The lock is associated with an object. So the thread is added to the wait set of the object.

All told, the object has the lock needed to block other threads until the thread completes the wait action. Therefore, the thread waits on the object.

Now, suppose another thread T wants to notify waiting threads that the condition has changed. We don�t want T executing notify while threads are in the act of waiting. We need to block T while a waiting action is going on. So we make T use the same lock as the waiting threads. T must invoke notify on the object that has the lock.

----

This explanation is not crystal clear. I think I did some hand-waving near the end.
[ June 05, 2004: Message edited by: Marlene Miller ]
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Marlene. Summarising - a wait set must be associated with a monitor lock or you'd get all kinds of race conditions. In Java, a lock is associated with an object.

The only thing one might add is that Doug Lea's concurrency library - to be included in JDK 1.5 as java.util.concurrent - builds a much richer set of concurrent programming concepts on top of Java's low-level monitor infrastructure.

- Peter
 
Dirk Schreckmann
Sheriff
Posts: 7023
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
srinibadri,

Welcome to JavaRanch!

We ain't got many rules 'round these parts, but we do got one. Please change your display name to comply with The JavaRanch Naming Policy.

Thanks Pardner! Hope to see you 'round the Ranch!
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Peter for reviewing what I said.

In truth, I know that I don�t completely understand what I am trying to explain. That�s why in my first explanation I deferred to history and references. In my second explanation, "therefore" is slightly premature.

The idea of a race condition I learned from The Java Programming Language 10.4. But that�s only part of the story.

In Concurrent Programming in Java, Lea talks about state dependence and guarded methods. State which represents the condition is another part of the story.

State, the condition and objects. Locks, critical regions and methods. How does it all fit together? Objects have locks and wait sets. Why? Objects serve as monitors. Why is a monitor what it is? Monitors solve the race condition at a higher level than semaphores to ensure a thread does not proceed until some specific condition holds.
[ June 05, 2004: Message edited by: Marlene Miller ]
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!