aspose file tools*
The moose likes Threads and Synchronization and the fly likes wait notify not working as expected Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "wait notify not working as expected" Watch "wait notify not working as expected" New topic
Author

wait notify not working as expected

vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
below is the code:

class MyThread extends Thread
{
int i;

MyThread(int ii, String name)
{
super(name);
i = ii;
}

public synchronized void run()
{
if (i == 10)
{
System.out.println(getName() + ": before wait");

try
{
wait();
}
catch (InterruptedException ie){ }

System.out.println(getName() + ": after wait");
}
else
{
notifyAll();
System.out.println(getName() + ": after notify");
}
}
}

public class Test
{
public static void main(String[] args)
{
Thread t1 = new MyThread(10, "A");
Thread t2 = new MyThread(20, "B");

t1.start();
t2.start();
}
}

output:

A: before wait
B: after notify

why thread A did not came out of wait state after notifyAll method is called by Thread B?
Edward Harned
Ranch Hand

Joined: Sep 19, 2005
Posts: 291

Start here


Ed's latest article: A Java Parallel Calamity http://coopsoft.com/ar/Calamity2Article.html
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
Edward Harned, thanks for the link.

i know the basics of thread and synchronization. it would be highly appreciable if you can figure out the bug in above code.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18117
    
  39

Basically, wait and notify is object based. Thread A is waiting on a different object than Thread B. So thread B notify is lost as there is no thread waiting for it.

Henry
[ June 28, 2007: Message edited by: Henry Wong ]

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

Joined: Jun 28, 2007
Posts: 191
Henry Wong, i got you a little bit. can you please modify the above code to work properly. thanks.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18117
    
  39

Originally posted by vikas chess:
Edward Harned, thanks for the link.

i know the basics of thread and synchronization. it would be highly appreciable if you can figure out the bug in above code.


Vikas,

I think it may be a good idea to start with the link provided by Edward. You should have an understanding of the basics of the wait/notify mechanism -- not to mention that the tutorial has plenty of examples.

Henry
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
Originally posted by Henry Wong:


Vikas,

I think it may be a good idea to start with the link provided by Edward. You should have an understanding of the basics of the wait/notify mechanism -- not to mention that the tutorial has plenty of examples.

Henry


man, i already have good understanding of threads and synchronization related stuffs. i too have the theoritical knowledge of wait and notify/notifyAll stuffs.

now i want to implement wait-notify. but i stuck in the above code. and now i am granting help from experts. it would be great if you can do correction in the above code.
Edward Harned
Ranch Hand

Joined: Sep 19, 2005
Posts: 291

We're not here to write your code. Your posted code reflects no comprehensive understanding of threading. You wait() and notify() in the same block of code.

Use the tutorial code.
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
Yup it's quite frustating when people do not answer to questions when they know the answer. But believe I have learnt a lot because of such people. If someone tells you where the problem is you wouldn't go in the process of solving the problem yourself. Which inturn at times lets you unravel various other things.

As this has helped me hoping this would help you as well. Not telling you the answer. Try if these hints help you a bit.

When you say public synchronized void run on which object have you obtained the lock? Are t1.i and t2.i always gauranteed to have the same value?
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18117
    
  39

Originally posted by vikas chess:


man, i already have good understanding of threads and synchronization related stuffs. i too have the theoritical knowledge of wait and notify/notifyAll stuffs.

now i want to implement wait-notify. but i stuck in the above code. and now i am granting help from experts. it would be great if you can do correction in the above code.



--- Previous Note Deleted ---




Okay, I deleted the solution... Thanks Edward and Anupam for reminding me that this is a learning site.

Henry
[ June 28, 2007: Message edited by: Henry Wong ]
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
i corrected the bug in my code. i was not invoking wait method inside a loop.

by changing the code as below it works fine:

if (i == 10)
{
System.out.println(getName() + ": before wait");

while(flag) // flag is a static boolean variable
{
try
{
wait();
}
catch (InterruptedException ie) { }
}

System.out.println(getName() + ": after wait");
}
else
{
flag = false;
notifyAll();
System.out.println(getName() + ": after notify");
}

thanks everyone
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
Originally posted by Henry Wong:
Basically, wait and notify is object based. Thread A is waiting on a different object than Thread B. So thread B notify is lost as there is no thread waiting for it.

Henry

[ June 28, 2007: Message edited by: Henry Wong ]


thanks henry,

i rewrite the code as follows:

class MyThread extends Thread
{
int i;

MyThread(int ii, String name)
{
super(name);
i = ii;
}

static Object lock = new Object();

public void run()
{
synchronized(lock)
{
if (i == 10)
{
System.out.println(getName() + ": before wait");

try
{
lock.wait();
}
catch (InterruptedException ie) { }

System.out.println(getName() + ": after wait");
}
else
{
lock.notifyAll();
System.out.println(getName() + ": after notify");
}
}
}
}

and it works fine!

but now the question is why in the above code, loop is not required to enclose wait() as stated in the note below:

http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
Hi Vikas

Though invoking wait() inside the while loop is a good idea. Though it may have given you the desired output there's still problems with the code. I would suggest that you follow the tutorial and try and answer that were asked in this thread.
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
Originally posted by Anupam Sinha:
Hi Vikas

Though invoking wait() inside the while loop is a good idea. Though it may have given you the desired output there's still problems with the code. I would suggest that you follow the tutorial and try and answer that were asked in this thread.


you are right anupam. i realized that very soon and corrected the problem. now it's working fine as you can see in my previous post.

i am very thankful to all of you. now i understood the concept of wait notify very well.
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
My previous post was for your previous post

You now you are waiting on common shared between threads object. You can also obtain a lock on (MyThread.class) and use it instead of creating a lock object. In your earlier program you were obtaining locks on t1 and t2 which are infact 2 different objects.

There are still some problems with your program. What if the t2 runs first and invokes notifyAll much before t1 has started to wait on lock.

[vikas chess]:but now the question is why in the above code, loop is not required to enclose wait() as stated in the note below:

Maybe I am missing something, but I think that the author did not intended to say that a while loop is not requried. According to me it introduces the concept of the wait method.
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
Originally posted by Anupam Sinha:

There are still some problems with your program. What if the t2 runs first and invokes notifyAll much before t1 has started to wait on lock.


for solving the above problem, i could modify the code as follows:

t1.start();
while (!t1.isAlive());
t2.start();

is it the best way. or their exist any better solution to the above issue.
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1088
Generally when multiple threads work and use wait/notify/notifyAll generally they are working on some common data. Genrally that common data is checked for getting into wait. Now in this case only the lock is obtained on a common object but the common object itself is not used for any manipulation.

[vikas chess]: t1.start();
while (!t1.isAlive());
t2.start();

is it the best way. or their exist any better solution to the above issue.


While this would not allow t2 to run till t1 is alive, but still it would not solve the problem. I think that semicolon after while (!t1.isAlive()); was a typo. If it was then the program won't ever complete and if not it doesn't solve anything.

Infact in one of your attempt you solved this. Try seeing one of your above post. This would also give you an idea why wait should always be invoked inside of a while loop.
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
Originally posted by Anupam Sinha:
Infact in one of your attempt you solved this. Try seeing one of your above post. This would also give you an idea why wait should always be invoked inside of a while loop.


if we should enclose loop around wait() for this reason only then the same problem can be solved by using if condition also as i did in the below code (am i right?):

class MyThread extends Thread
{
int i;
static boolean flag = true;

MyThread(int ii, String name)
{
super(name);
i = ii;
}

public void run()
{
synchronized(MyThread.class)
{
if (i == 10)
{
System.out.println(getName() + ": before wait");

if(flag) // if condition instead of loop
{
try
{
MyThread.class.wait();
}
catch (InterruptedException ie) { }
}

System.out.println(getName() + ": after wait");
}
else
{
flag = false;
MyThread.class.notifyAll();
System.out.println(getName() + ": after notify");
}
}
}
}

public class Test
{
public static void main(String[] args)
{
Thread t1 = new MyThread(10, "A");
Thread t2 = new MyThread(20, "B");

t2.start(); // t2 is started first intentionally here
t1.start();
}
}
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18117
    
  39

but now the question is why in the above code, loop is not required to enclose wait() as stated in the note below:

http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html


Keep in mind that just because your code works, doesn't mean that it is a bad idea. There are two rules that you should follow -- which basically is the reason why you use a while loop with a flag.

First, you should always check to see if you should wait. In your example, what if the notified happened first. There is not enough state between the two threads, you should not use a notification blindly.

What if you have multiple waiting threads? It is possible for a notifier to send the notification, but before a thread wakes up, an already awoke thread goes and handles it (which unsets the flag)... so Second, you should always check a flag after you wake up from a wait() as it may have been already handled.

So how do you do both of thesse? Create a flag, and check it in a while loop -- exact what you have done.

Henry
[ June 29, 2007: Message edited by: Henry Wong ]
vikas sharmaa
Ranch Hand

Joined: Jun 28, 2007
Posts: 191
Originally posted by Henry Wong:


First, you should always check to see if you should wait. In your example, what if the notified happened first. There is not enough state between the two threads, you should not use a notification blindly.

What if you have multiple waiting threads? It is possible for a notifier to send the notification, but before a thread wakes up, an already awoke thread goes and handles it (which unsets the flag)... so Second, you should always check a flag after you wake up from a wait() as it may have been already handled.

So how do you do both of thesse? Create a flag, and check it in a while loop -- exact what you have done.

Henry

[ June 29, 2007: Message edited by: Henry Wong ]


oh fabulous!

very thanks to all especially Henry and Anupam, now i don't have any doubt remaining. you people are awesome.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: wait notify not working as expected
 
Similar Threads
Wait and notify sample does not work
Thread Priority
Thread Synchronization
newbie a help is appreciated
Threading synchronization