Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

java notify wait

Hi,

I am working on below example

http://www.avajava.com/tutorials/lessons/how-do-i-use-the-wait-and-notify-methods.html

I have not understood what author is trying to demonstrate as below
The Object class in JavaSW has three final methods that allow threads to communicate about the locked status of a resource. These methods are wait(), notify(), and notifyAll(). A thread obtains a lock for a particular resource via a synchronized block with an instance of that resource. Suppose that a thread requires that another thread perform a certain action on the resource before it acts on the resource. That thread can synchronize on the resource and call the wait() method on resource. This says that the thread will wait until it has been notified that it can proceed to act. The wait() method can take an optional timeout value as a parameter. If this value is used, it means that the thread will either wait until it's notified or it will continue to execute once the timeout value has passed.

If a thread is required to perform a task on a resource before another thread operates on the resource (and the other thread is waiting via the wait() method on the resource), the thread needs synchronize on the resource. It can perform its actions on the resource. In order to notify the waiting thread once these actions have completed, the notify() method on the resource is called. This notifies the waiting thread that it can proceed to act. If multiple threads are waiting for the resource, there is no guarantee as to which thread will be given access to the resource. If it is desired for all waiting threads to be awoken, the notifyAll() method can be called on the resource.

also below not clear along with output
wait/notify is that it avoids polling (checking over and over to see if a resource is ready to be used), since polling can be expensive in terms of system resources.


output

Waiter is waiting for the notifier at Fri Feb 07 18:09:12 EST 2014
Notifier is sleeping for 3 seconds at Fri Feb 07 18:09:12 EST 2014
Notifier is notifying waiting thread to wake up at Fri Feb 07 18:09:15 EST 2014
Waiter is done waiting at Fri Feb 07 18:09:15 EST 2014
Waiter got the message: Notifier took a nap for 3 seconds


please advise
Any links resources ideas highly appreciated. Thanks in advance
Avatar of Gary Patterson, CISSP
Gary Patterson, CISSP
Flag of United States of America image

Sometimes in multi-threaded applications, one thread needs to wait on another to complete.  

Let's say that Thread1 needs Thread2 to do something for it, and cannot proceed until Thread2 completes at least part of the task.

After handing off to Thread2, Thread1 could POLL - sit in a loop and repeatedly check Thread2 to see if it is done with the critical part of the job.  For very, very short waits, this is fine, but for longer waits, it is very inefficient.  

This is called a "busy wait" because Thread1 is actively running and consuming CPU cycles as it repeatedly polls Thread2:

Are you done yet?
Are you done yet?
Are you done yet?
Are you done yet?

This is inefficient, since Thread1 consumes CPU cycles continually while it is polling - and it will be a lot of CPU cycles if Thread1 doesn't sleep for a bit (give up the CPU) between each poll.  

This means that the CPU can't be used for other useful work in the system during this period.

To reduce the amount of CPU burn, you can add a delay to the polling loop:

Are you done yet?
Sleep for a while
Are you done yet?
Sleep for a while
Are you done yet?

That will reduce CPU usage, but in high-volume applications, there is always some wasted time at the end of the last sleep cycle - the time between the time Thread2 is done, and the time Thread1 wakes up from the last sleep.  That may not sound bad, but those extra delays can really add up in high-volume applications, and cause longer than needed runtimes.  

I recently helped fix a polling problem in an application.  

In the first version of the program, the programmer polled without any delay, and as a result, the waiting thread consumed 100% of one CPU - while doing nothing useful other than polling thousands of times per second.  

So the programmer added a 1,000ms delay in the polling loop.  That fixed the CPU burn problem - not Thread1 only used a tiny bit of CPU once every second - but since the average runtime of Thread2 was only about 5ms, for every transaction, there was an average of 995ms of wasted time in each transaction.  

The application processed millions of transactions, so total job runtime went through the roof - and most of the time Thread1 sat around doing nothing.  

Instead of polling, a better approach for anything but very short waits is NOTIFICATION.

Using notification, Thread1 hands off the work to thread2, and then executes a wait(), which tells the scheduler to put the thread to sleep until Thread2 issues a notify().  

When Thread2 issues the notify(), the scheduler wakes Thread1 up, and it immediately continues, with no wasted time waiting on a timed delay, and Thread1 doesn't use the CPU while waiting.

Polling works fine for every short waits, since notification does create some additional overhead, so there is a place for polling.  But for anything but the shortest waits, notification is a good way to go.
Avatar of gudii9

ASKER

So the programmer added a 1,000ms delay in the polling loop.  That fixed the CPU burn problem - not Thread1 only used a tiny bit of CPU once every second - but since the average runtime of Thread2 was only about 5ms, for every transaction, there was an average of 995ms of wasted time in each transaction.  


Polling works fine for every short waits, since notification does create some additional overhead, so there is a place for polling.  But for anything but the shortest waits, notification is a good way to go.


How to handle in case of long waits since the scenario you mentioned with long wait also seems creating problem.
A thread obtains a lock for a particular resource via a synchronized block with an instance of that resource. Suppose that a thread requires that another thread perform a certain action on the resource before it acts on the resource. That thread can synchronize on the resource and call the wait() method on resource.
They are talking about thread1 right in above line.

In this example which one is thread 1, thread 2, synchronized block and where they used wait(), notify()





please advise
In my example,

Thread1 dispatches work to Thread2 and issues a wait()
Thread2 performs the work, and then issues a notify() when it is done, allowing Thread1 to proceed.

In the avajava example:

1) WaitNotifyExample sets up a Message object called "message" with the text "Howdy".  

"message" is a shared resource that will be accessed by all three threads.

Access to "message" needs to be synchronized between "waiter"  and "notifier" to prevent "waiter" from accessing "message" until "notifier" has changed the message.text.

2) WaitNotifyExample then launches two threads, and passes each of them a pointer to "message".  First it starts "waiter", then it starts 'notifier".

The main thread - WaitNotifyExample - terminates.

So now we have 2 threads running:  "waiterThread", and "notifierThread".

3) "waiter" prints "Waiter is waiting for the notifier at ...".

"waiter" wants to leave "message" unchanged until "notifier" is done with "message", so "waiter" synchronizes on "message", and issues message.wait() and goes to sleep.  waiterThread execution pauses here.

4)  Meanwhile, "notifier", running in thread notifierThread prints "Notifier is sleeping for 3 seconds ...", and then sleeps for 3 seconds.  

"waiter" is still asleep, waiting on notification that it can proceed.

5) After sleeping for 3 seconds, notifierThread wakes up, changes the message.text to "Notifier took a nap for 3 seconds" and prints "Notifier is notifying waiting thread to wake up at...".

6) "notifier" issues message.notify(), which wakes "waiterThread".

7) "waiter" prints "Waiter is done waiting at..." and then prints "Waiter got the message: " + message.getText()".  message.text contains the text that Notifier assigned.
Avatar of gudii9

ASKER

Thread1 dispatches work to Thread2 and issues a wait()
Thread2 performs the work, and then issues a notify() when it is done, allowing Thread1 to proceed

Thread1 dispatches work to Thread2 and issues a wait() to itself(Thread1) right?

Thread2 performs the work, and then issues a notify() to Thread1 right?(not to cpu/jvm?)


"message" is a shared resource that will be accessed by all three threads.


I thought only 2 threads waiterThread, notifierThread.


Access to "message" needs to be synchronized between "waiter"  and "notifier" to prevent "waiter" from accessing "message" until "notifier" has changed the message.text.
I do not see message being synchronized in neither WaitNotifyExample  class nor other classes.
please advise
Re-read my last comment.
Avatar of gudii9

ASKER

I see main is 3rd thread.
Avatar of gudii9

ASKER

I see

synchronized (message) {

in both Waiter and Notifier classes
Avatar of gudii9

ASKER

so wait() is for Thread1(waiter) to wait on resource to be used once notify message comes from Thread2 after completing its use on the resource.

So wait() command is like self command ie command to itself whereas notify is command to other ie to other thread here Thread1(waiter). Please confirm if my understanding is correct?
Avatar of gudii9

ASKER

In order to notify the waiting thread once these actions have completed, the notify() method on the resource is called.




That thread can synchronize on the resource and call the wait() method on resource



Looks like author in the link is mentioning wait, notify on the resource. Is that is how it has to be thought? please advise
ASKER CERTIFIED SOLUTION
Avatar of Gary Patterson, CISSP
Gary Patterson, CISSP
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial