img
.
In Code Example 7-4 we are faced with a serious situation. Evil space aliens are trying to kidnap
Elvis in order to breed him with other Earthlings. To save him, we must eliminate the aliens
quickly. If we fail to do so within a short time (10 seconds), they will escape with him and rock
and roll will be lost.
Example 7-4 Recalculating Timeouts
public synchronized void saveElvis() throws InterruptedException {
long timeRemaining, time = 10000;
// 10 seconds
while (!eliminatedAliens()) {
timeRemaining = timedWait(time);
if (timeRemaining == 0)
return false;
// Too late. Elvis kidnapped.
time = timeRemaining;
}
return true; // Elvis lives!
}
public long timedWait(long waitTime) throws InterruptedException {
long now, timeSoFar, startTime;
startTime = System.currentTimeMillis();
wait(waitTime);
now = System.currentTimeMillis();
timeSoFar = now - startTime;
if (timeSoFar > waitTime) {
return 0;
}
waitTime =  (waitTime - timeSoFar);
return waitTime;
}
Our main method [saveElvis()] will sit in a while loop, waiting for us to eliminate the aliens.
If we succeed, we'll return true from saveElvis(). If we time out, we'll return false. If our
wait call returns before the time-out period and the aliens are not eliminated (perhaps some new
aliens hatched from evil alien pods, perhaps we just suffered a spurious wakeup), we will go back
and wait again. When this happens, we want to calculate the correct remaining time (instead of
starting over with a new 10 seconds). Our timedWait() method will do this for us by returning
the remaining time.
This method does the majority of the work. It records the starting time and calls wait() with the
appropriate timeout. When wait() returns, it calculates how much time has elapsed. If it's more
than the original timeout period, timedWait() returns . If it is less, timedWait()
recalculates how much time is remaining and returns that, leaving it up to the caller to decide what
to do. If the caller calls it again, it will wait again for the appropriate amount of remaining time.
This is a bit awkward, but it does give the desired results.
It doesn't make any difference should another thread wake up the sleeper 1 ms after it has timed
out. It also makes no difference should it subsequently take the ex-sleeper 16 hours to become
active or acquire the lock. On the other hand, once the sleeper is awakened, it is taken off the sleep
queue and the timer is turned off. If it takes another week before the wait function can get the
required lock and returns, too bad. You will not get a timeout.
Search WWH :
Custom Search
Previous Page
Multithreaded Programming with JAVA - Topic Index
Next Page
Multithreaded Programming with JAVA - Bookmarks
Home