views:

164

answers:

4

I think the topic might not be accurate enough, but I really don't know how to describe it in a very brief way...

What I want to do is as follows: I have a process running some analysis (in Java) and trying to give a return value, but the whole analysis has a time constraint, say 10 seconds

If the analysis gives a result within 10s, return the result; else, times up when reaching 10s, stop the process and return a dummy value

I am a newbie in this field, any suggestions will be welcomed.

A: 

Take a look at java.util.concurrent.Future, particularly the get(long timeout, TimeUnit unit) method:

Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.

Michael Myers
calling get() alone does not address this question, as the questions explicitly states to "stop the process"
Tim Bender
+1  A: 

You could use a timer (java.util.Timer), which you could notify of the thread, and then when the timer expired it could tell the thread to stop.

A better solution would be to spawn the process off into it's own thread, and then tell your main thread to wait on the processing thread and sleep for 10 seconds. When it finishes, you can send the thread a stop signal. Note: I would not use the stop() method, and instead send either a signal or set a value through a synchronized method that gets checked every so often during the execution.

aperkins
Wow, I should take a screenshot: Both our answers say "answered **0 secs ago** ".
Michael Myers
Note that stop() is deprecated
Brian Agnew
@Brian yeah, I should have been more clear about WHY I wouldn't have used it :P
aperkins
+2  A: 

You can use FutureTask to create a job and request the result within a particular time (using get() with a timeout). If that time window is breached, then you'll get an exception.

At that point you can then call the cancel() method with the parameter set to true to force an interruption and cancel the underlying task.

Object result = DUMMY;
try {
   result = futureTask.get(5, TimeOut.SECONDS);
}
catch (TimeoutException e) {
   futureTask.cancel(true);
}
Brian Agnew
I don't think you need to cancel. It says: "Throws: `TimeoutException` - if the wait timed out"
Michael Myers
Yes, but the questioner *then* wants the underlying task cancelled, which I believe is distinct from the get() not receiving a value in time
Brian Agnew
Doesn't the exception count as cancelling the operation? Maybe it doesn't.
Michael Myers
I don't believe so
Brian Agnew
A: 

I had a similar issue when writing a game AI that used Minimax, the requirement was to return within 5 seconds with a move. I tested using a Timer to set a boolean flag in my code which was checked periodically, there were no performance gains over using a call to System.currentTimeMillis().

So if the dummy value you want to return is actually some partial solution, I recommend that you store the system's time in a long and check periodically to see if you ten seconds are up and return whatever value you have left.

Otherwise, use FutureTask and call the get method on it with your timeout. One thing Brian didn't mention though is that your code doing the processing has to check if it has been interrupted periodically in order to actually stop execution early.

Tim Bender
That's a good point re. interrupts, since I believe they only will interrupt the thread on an IO call
Brian Agnew