• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

wait notify not working as expected

 
Ranch Hand
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Ranch Hand
Posts: 291
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Start here
 
vikas sharmaa
Ranch Hand
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
vikas sharmaa
Ranch Hand
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Henry Wong, i got you a little bit. can you please modify the above code to work properly. thanks.
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 291
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 191
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic