File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes Wait and Notify Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Wait and Notify" Watch "Wait and Notify" New topic
Author

Wait and Notify

adithya narayan
Ranch Hand

Joined: Jan 05, 2009
Posts: 79

Hi,

I wrote a program which will have two threads; one thread will check for numbers between 1 to 100 and if encounters any number which is a multiple of 10 (modulus) then notify the second thread ,so that it will carry out a special operation on the same number.

Below is the code i have written :



I was expecting the output to be something like this :



..but it didn't happen so !

instead it printed some like this

First output:


Second output:



1)Can anyone explain what went wrong?
2)The program didn't terminate. How do i terminate it?


Thanks,
Adithya.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18103
    
  39

adithya narayan wrote:
1)Can anyone explain what went wrong?
2)The program didn't terminate. How do i terminate it?


A few points...

1. The notify() method doesn't trigger the wakeup, context switch, etc.... all it does is send the notification to a waiting thread.
2. A notification that is sent, and there is no waiting thread, is ignored.
3. The wait and notify mechanism is integrated with the synchronization mechanisms because there are race conditions that need to be taken care of.

so...

Your waitandnotifytest thread just sends the notification, and does so blindly in a loop (no flag to confirm receipt, or that a thread is waiting)... see point one and two. This causes a bunch of missed notifications.


And the reason your program doesn't end is because your waitingrunnable thread has an endless loop.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
adithya narayan
Ranch Hand

Joined: Jan 05, 2009
Posts: 79

Hi Henry,


ahhh..right i completely overlooked that the code was running in an infinite loop !

But it still doesn't make it any clear to me as to why certain notifications weren't caught by the waiting thread !!

I was under the impression that :

1)When a synchronized block is executing (by holding the lock on a third party object) no other object can enter that block or acquire the object's lock. Also when one wants to call wait/notify on an object it needs to acquire the object's lock. So according to my understanding the waiting thread calls wait and releases the object lock so other threads can use it.
Now the notifying thread acquires the lock performs certain operations inside the synchronized block and calls notify. As soon as it exits the synchronized block it releases the object lock.
Next the waiting thread comes out from the blocking state ,acquires the object lock and performs the necessary operations. Meanwhile ,if the notifying thread wants to enter the synchronized block again it will require the object lock !!
So,i thought the expected and actual output would match.

I am not able to figure out what i am missing.

I understood why you pointed out the following to me :


The notify() method doesn't trigger the wakeup, context switch, etc.... all it does is send the notification to a waiting thread.


and that's because my following piece of code was misleading:


I should have written that in the waiting thread.
as


Your second point is also understood


I didn't understand the condition you were talking about. I really didn't feel that there should be condition which will monitor the wait/notify events. Please clarify if i am missing anything.


Your waitandnotifytest thread just sends the notification, and does so blindly in a loop (no flag to confirm receipt, or that a thread is waiting)... see point one and two. This causes a bunch of missed notifications.


Why does it cause notifications to be missed ?


Thanks,
Adithya.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 3934
    
  17

You expect things to happen in a specific order:

1: The waiter waits
2: The notifier notifies
3: The waiter gets signal and works
-- repeat

But this isn't guaranteed. What can happen is the notifier notifies before the waiter waits. In this case, the waiter never sees the notify. Additionally, once the notify is sent, it does not ensure that the waiter gets the lock next. What actually happens is that the waiter and notifier 'compete' for the lock. So the notifier may get the lock and send another signal, and another, and another before the waiter ever gets a chance to respond.

If it is important that the waiter respond to every notify then you need two way signaling, like a flag which the waiter sets to let the notifier know it is ready, or a return signal which let's the notifier know its signal was received.


Steve
adithya narayan
Ranch Hand

Joined: Jan 05, 2009
Posts: 79

I get it now to an extent ! I modified my code accordingly and got near about to the output i wanted.

Below is the code :


and the output is as follows:



This is how wait and notify works i guess. The notifying thread notifies the worker thread that it can stop waiting and continue its execution and meanwhile the notifying thread executes its own operation. Am i right? Also i have kept a check to ensure that each and every notification is captured by the waiting thread by using the flag

.

So,the notifying thread cannot re-enter the synchronized block until the waiting thread finishes its previous execution; till then the notifying thread is blocked.

I am still unable to get to the output which i had desired i.e. The notifying thread should increment the value of the counter only after the waiting thread finishes its previous execution based on the notification sent by the notifying thread ! Also,the notifying thread shouldn't notify for the same event again. Can anyone suggest something ?


Thanks,
Adithya.



Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18103
    
  39

adithya narayan wrote:
I am still unable to get to the output which i had desired i.e. The notifying thread should increment the value of the counter only after the waiting thread finishes its previous execution based on the notification sent by the notifying thread ! Also,the notifying thread shouldn't notify for the same event again. Can anyone suggest something ?


Correct. That is what you need to do. Right now, all you do is to not do another notify, you don't wait, you just move on to the next value.

Henry
adithya narayan
Ranch Hand

Joined: Jan 05, 2009
Posts: 79

I want to move to the next value only if the waiting thread has finished its execution.

Something like
1)i=1,2,3,4,5,6,7,8,9, 10..meanwhile,waiting thread is waiting (lets forget 0 for time being)
2)now notification happens and is blocked until waiting thread executes its work and tells the notifying thread to resume..
3)now notifying thread continues i=11,12,13,14,15,16,17,18,19,20..the same process continues
.
.
.
and so on.

I did think of many options but i am seeing one possibility of both the threads having the roles of waiting and notifying..i fear deadlock might occur.

Thanks,
Adithya.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 3934
    
  17

You should be able to use wait() and notify() like this. The counting thread would first wait() for a signal from the WaitingRunnable so it knows the WaitingRunnable is actually waiting. Then it sends a notify(), then it wait()s for when the WaitingRunnable is done. Meanwhile the WaitingRunnable first notify()s that it is going to wait. It then wait()s, does its work, and then notify()s. You would need booleans to check and prevent extra wait()s from occurring. It can be a bit tricky.

So a better option might be to employ one of the signaling mechanisms in the java.util.concurrent package. I am thinking either an exchanger or CyclicBarrier. The Exchanger may be best since you want to share data - it can prevent the need for sharing the modulo value all together (just pass it back and forth). Here is an example:

 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Wait and Notify
 
Similar Threads
problem in threads(sun accesibility test)
How would i shuffle my deck of cards?
Strange behavior for enhanced ForLoop.
can rectangle be drawn in jpanel using awt classes
A Hard Puzzle