• Post Reply Bookmark Topic Watch Topic
  • New Topic

Problem with wait()

 
Piotr Nowakowski
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

When I execute the following code


a result is:
Waiting for Calc
Waiting for Calc
Waiting for Calc
Waiting for Calc
Waiting for Calc
TIME OUT
Result is = 99
TIME OUT
Result is = 99
TIME OUT
Result is = 99
TIME OUT
Result is = 99
TIME OUT
Result is = 99


so it surprisingly contains "TIME OUT" and "Result is = 99" lines although the Reader threads are (or should be) in the WAITING state.
The code wouldn't change its behaviour if I used notifyAll() after "done = true;" line in Calc class.

In my opinion a scenario for the code is:
1) one of the threads acquires lock on Calc object
1.1) if the thread is the Calc thread, it goes to sleep for at least 1 second
1.2) if the thread is one of the Reader thread, it changes its state to the WAITING state and release the lock (some other Reader threads can also change their state before Calc object acquires the lock)
2) others Reader threads change their state to WAITING and release the lock
3) Calc object acquires the lock and executes its code
4) Calc object release the lock (and don't execute any notify method)
5) Reader threads remain in WAITING state

but in that case the 5th step is following:
5*) Reader threads change their state to READY and then to RUNNING and they execute the rest of their code

Why does it happen ?
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We discussed a similar one to this a while back ....

I think you're missing Calc thread completes run, thread death causes all waiting threads to be signalled. It's a feature, I presume to get you out of the scenario you have written ;-) . Try adding the following system out and play with say add a second wait which waits forever where I have the println.

 
Piotr Nowakowski
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply, but is there any documentation/specification quote which says that "thread death causes all waiting threads to be signalled" ?
If I used different obejct as a lock - let's say Object lock = new Object() - the problem wouldn't occur and the threads would be in WAITING state.
So it means the thread death wouldn't cause all waiting threads to be notified, except for the case in which the object which is locked is the thread object itself.
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes to be clear it's because your waiting on the thread object.

There was another example of this in one of the earlier posts on this forum where we discussed it, hopefully in a bit more detail.
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thinking about it ...

The formal documentation would go along the lines of 'spurious thread wake up' , i.e. java can wake up a thread any time its likes (as per unix) , this is covered by the documentation on object.wait i.e. you don't need a notify which is why you should test a variable when you wake up.

It happens that in this case the reason you wake up is because you were waiting on the thread object and that thread completed its run and effectively signalled. I believe this was a java change at some point ie some very old JVM's didn't do it and they did it to avoid the scenario you had and could make this change because the contract of wait allows it ;-)
 
Piotr Nowakowski
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the explanation.
 
Henry Wong
author
Sheriff
Posts: 22529
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piotr Nowakowski wrote:Thanks for the reply, but is there any documentation/specification quote which says that "thread death causes all waiting threads to be signalled" ?
If I used different obejct as a lock - let's say Object lock = new Object() - the problem wouldn't occur and the threads would be in WAITING state.
So it means the thread death wouldn't cause all waiting threads to be notified, except for the case in which the object which is locked is the thread object itself.


Short answer... You have a conflict with the core library. The core library uses the Thread object to notify waiting threads attempting a join(). So, don't use the Thread object for notifications -- the library is using it.

Chris Hurst wrote:
The formal documentation would go along the lines of 'spurious thread wake up' , i.e. java can wake up a thread any time its likes (as per unix) , this is covered by the documentation on object.wait i.e. you don't need a notify which is why you should test a variable when you wake up.

It happens that in this case the reason you wake up is because you were waiting on the thread object and that thread completed its run and effectively signalled. I believe this was a java change at some point ie some very old JVM's didn't do it and they did it to avoid the scenario you had and could make this change because the contract of wait allows it ;-)


I think it would be a good idea to not link this. The Java thread library have a "spurious wake up" requirement, because the underlying libraries (actually, the majority of them) have a "spurious wake up" requirement. But, in this case, even if the underlying library didn't have a "spurious wake up" requirement, it will still wake up, as you have a conflict.

Henry
 
Chris Hurst
Ranch Hand
Posts: 443
3
C++ Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I believe this (side effect) was historically reported as a bug against java which is where I first found it and from memory the Sun engineers response was that it was not a bug but an example of spurious thread wake up i.e. we never said that wait wouldn't just wake up so you can complain when it exhibits that behaviour and they linked to the definition of wait. It is slightly odd in that even if the underlying threading model doesn't exhibit spurious wake up that java might but I guess that's the same argument as that an OS can exhibit a strong memory model but Java might still behave as if a weak one.
 
Henry Wong
author
Sheriff
Posts: 22529
109
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chris Hurst wrote:
I believe this (side effect) was historically reported as a bug against java which is where I first found it and from memory the Sun engineers response was ...


First, have a cow for the story. I found it interesting...

Having said that, I felt that the Sun engineer basically punted the problem. I doubt that he/she even knew there was a conflict. Kinda lazy in my opinion. Or in a hurry to close trouble tickets.

Henry
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!