Win a copy of Soft Skills: The software developer's life manual this week in the Jobs Discussion forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How know thread.wait( timeout) has timed out?

 
Dan Bizman
Ranch Hand
Posts: 387
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you call someObject.wait( 1000 ) and it timesout, as opposed to some other thread calling notify(), how do you know that?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There's no way to tell directly - that is, you would have to add additional code to determine this. Often when you wait(), you're waiting for something to happen which changes the state of an object in some way - e.g. by setting a boolean variable, perhaps. If that's the case, then you may be able to simply check the state of that variable to see if the event occurred, or you merely timed out. Or you can look at the value of System.currentTimeMillis() to see i the elapsed time is greater than or equal to the timeout period - if it is, that would be a clue you have probably timed out (though it's not an absolute guarantee). Or if the elapsed time is less than the timeout period then you certainly have not timed out. Does that help?
 
Henry Wong
author
Marshal
Pie
Posts: 20817
75
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are two rules of thumb with using wait and notify.

First, always confirm that you actually need to wait before calling the wait() method -- you may not need to call the wait() method. Second, always confirm that the state is what you want upon returning -- you may need to wait again. Of course, this confirmation and reconfirmation should be done with the synchronization lock.



Anyway, under these rules, you don't need to know if the notification is recieved or if the operation timed out, you know the actual state.



But to answer your question... you can't.

Henry
[ October 09, 2006: Message edited by: Henry Wong ]
 
Dan Bizman
Ranch Hand
Posts: 387
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
There's no way to tell directly - that is, you would have to add additional code to determine this. Often when you wait(), you're waiting for something to happen which changes the state of an object in some way - e.g. by setting a boolean variable, perhaps. If that's the case, then you may be able to simply check the state of that variable to see if the event occurred, or you merely timed out. Or you can look at the value of System.currentTimeMillis() to see i the elapsed time is greater than or equal to the timeout period - if it is, that would be a clue you have probably timed out (though it's not an absolute guarantee). Or if the elapsed time is less than the timeout period then you certainly have not timed out. Does that help?


That's what I ended up doing, but it's not really safe/accurate. Take the following code:



Since System.currentTimeMillis() and lock.wait() are actually two separate instructions, a lot can happen in between those. It's entirely possible for three other threads to get run by the CPU in between those calls. So imagine the following:

1. Call System.currentTimeMillis
2. Call lock.wait( ourTimeout )
3. Some other thread calls notify() and wakes us up at 20ms before "ourTimeout"
4. Another two threads get the CPU in succession and take 20 ms
5. Now when we call System.currentTimeMillis to check if we timed out, it
shows that we did, since we're now at the same time as "ourTimeout"

I really don't understand why they don't let you know you timed out. Obviously the JVM knows, so why not just return a boolean from this method? It wouldn't break any code (not even reflection).
[ October 10, 2006: Message edited by: Dan Bizman ]
 
Dan Bizman
Ranch Hand
Posts: 387
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Henry Wong:
There are two rules of thumb with using wait and notify.

First, always confirm that you actually need to wait before calling the wait() method


Yep, i'm doing that. I check some state value.


Originally posted by Henry Wong:
Anyway, under these rules, you don't need to know if the notification is recieved or if the operation timed out, you know the actual state.


that's not true. My application's users care about two things:

1. the state, as they can't do the action without the proper state
2. If it's taking too long, they want to quit the action attempt

I don't see why that second one isn't valid, nor how i can honor that without a timeout in wait (i.e. keeping it from blocking too long).
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24204
34
Chrome Eclipse IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Depending on the particulars, it may or may not be possible to be notify()ed when the state is not what you want. If this is not possible, then don't use the classic loop; instead, just recheck the state:

 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Dan]: but it's not really safe/accurate.

Using the current time doesn't tell you definitively whether you timed out of the wait or not, true. As I noted in the first place. But I'm at a loss to understand why this distinction matters to you. Either it timed out, or the notification occurred just a tiny bit before the timeout, or the notification occurred a more substantial amount of time ago, but the system has been unable to get around to running the thread yet. In all of these cases, what it boils down to is that the code has taken too long to get to this point, right? Aren't these all equivalent to timing out? What different action do you need to take here?

[Dan]: I really don't understand why they don't let you know you timed out.

Returning a boolean seems like a reasonable thing they could have done here. Maybe it didn't occur to them, or maybe they thought it might create a tiny performance hit. Honestly, the number of times you really need to know this is very small in my opinion, and I think there's always some workaround available.

[Dan]: My application's users care about two things:

1. the state, as they can't do the action without the proper state


There's no problem with this one, right?

[Dan]: 2. If it's taking too long, they want to quit the action attempt

I don't see why that second one isn't valid, nor how i can honor that without a timeout in wait (i.e. keeping it from blocking too long).



the second one is valid, but I don't see why System.currentTimeMillis() is not enough info for you to determine whether it's "taking too long".

You're waiting for some state transition, right? Just check if the current state fulfils the condition you need to continue. If it does, then you might as well continue, regardless of what the clock says. If not, and the clock tells you that timeout has occurred, then stop. How does this not meet your needs?

[EFH]: Depending on the particulars, it may or may not be possible to be notify()ed when the state is not what you want.

Note that the JLS3 does specifically allow implementations to perform spurious wakeups. So unless you're familiar with the internals of the particular JVM being used, and are confident the implementation won't change in the lifetime of the program, I think it's impossible to say that notification could only occur when the desired state is achieved. And thus, I think a while loop should be strongly preferred here.
 
Dan Bizman
Ranch Hand
Posts: 387
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
The second one is valid, but I don't see why System.currentTimeMillis() is not enough info for you to determine whether it's "taking too long".


Thanks (to both of you) for the response(s). I think you're right. I'm not writing any code that requires perfect precision, so I think the choice to check the time, even if it's off by 3 seconds, is adequate. I feel more comfortable with the choice now.
 
Dan Bizman
Ranch Hand
Posts: 387
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
BTW, Jim, I just read your signature and it's hilarious!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I thought so too - the credit goes to Maureen.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic