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 strange results from 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 "strange results from wait() and notify()" Watch "strange results from wait() and notify()" New topic
Author

strange results from wait() and notify()

Jarek Jankowski
Greenhorn

Joined: Jul 05, 2008
Posts: 13
Hi guys,
I've written a class Printer that,I thought, will notify the "main thread" about the fact that it wrote a message onto a screen. However, the program doesn't behave as I expected. I expected to see results like this:

BBB
Another thread printed a message onto a screen
BBB
Another thread printed a message onto a screen
BBB
Another thread printed a message onto a screen
and so on(10 such pairs)

while I most often get:
BBB
BBB
.
.
.
(ten times)
Another thread printed a message onto a screen
Program complete.

I tried debugging it and observed strange Printer object's lock exchange between the two threads.

Could anyone please help? I really have no idea why it gives such results.

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18101
    
  39

1. Your wait() loop gives up the lock without calling wait(). This means that it is possible for the notify to be called without the thread waiting.

2. If a notification is sent, and no-one is waiting, the notification is lost.

3. Both of your threads are accessing the done flag, without any synchronization.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Jarek Jankowski
Greenhorn

Joined: Jul 05, 2008
Posts: 13
Thanks Henry for your reply.
I understand and agree with your explanation in points 2 and 3.
As far as 1 is concerned, debugger showed me things that could justify your explanation. The main thread was very rarely on the Printer object's monitor. But how my wait() loop gives up the lock without calling wait()? I still don't how to fix this. Could you suggest some code changes so that I can undestand it thoroughly? Thanks.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24166
    
  30

The synchronized block in main() should be around the loop, not inside. Then the only way that control is surrendered to the Printer thread is by calling wait(). Otherwise, the Printer thread can do whatever it wants when the control part of the loop is executing outside the synchronized block, and that's when notifications can be lost.

A multithreaded program will act completely differently under a debugger, because stepping in a debugger obviously changes the timing of everything by a lot!


[Jess in Action][AskingGoodQuestions]
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18101
    
  39

But how my wait() loop gives up the lock without calling wait()? I still don't how to fix this.


Take a look at your loop....



As you see, you have the synch block inside the while loop. And there are periods just before and just after the sync block, yet within the loop, where the thread doesn't hold the lock, and not calling wait(). The fix is, of course, to have the while loop inside the sync block.

Could you suggest some code changes so that I can undestand it thoroughly? Thanks.


Well, you also shouldn't be waiting blindly. It may be better to have some state on which thread is supposed to print -- which gets toggled back and forth as the two threads are printing.

Henry
Jarek Jankowski
Greenhorn

Joined: Jul 05, 2008
Posts: 13
I've done like you said but there is no improvement. Additionally, the main thread does not die (it doesn't print 'Program complete').
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18101
    
  39

I've done like you said but there is no improvement.


That is because it is still possible for the printer to print "BBB", send the notification, release the lock, and then grab it back, repeat.

Sending the notification does not give the lock to the waiting thread. The printer can hold (release and regrab) onto the lock sending many notifications before the waiting thread gets it.

Additionally, the main thread does not die (it doesn't print 'Program complete').


This is caused by a race condition between setting the flag and the sync lock -- as it is possible for the waiting thread to get the lock between those two actions.

ie. --> Notification is sent. --> notification is recieved --> message is printed --> while loop checks for flag --> thread waits --> then the flag is set.

Henry
[ September 24, 2008: Message edited by: Henry Wong ]
Jarek Jankowski
Greenhorn

Joined: Jul 05, 2008
Posts: 13
Now it is clear. Thanks Henry.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: strange results from wait() and notify()
 
Similar Threads
Movement problems
without giving notify control comes back to print main
problem with awakening after nofifyall is called GUI Swing
Test Question about Threads
Bluetooth Chat application