Sometimes you want to set a timeout for something that doesn’t have a built in timeout functionality. What can you do if a setTimeout method is not present? for example in a web service?.
We can achieve this using some classes from the standard library of the java.util.concurrent package .
As with the last post we are going to keep things simple, for more detailed explanations and if you’re looking for more functionalities, please refer to the docs.
I made a simple class that implements the Callable interface:
import java.util.Random;
import java.util.concurrent.Callable;
import org.apache.log4j.Logger;
public class DummyCallback implements Callable<String>{
private Logger log = Logger.getLogger(this.getClass());
public String call() throws Exception {
Random r = new Random();
int time = r.nextInt(100);
log.info("waiting for: "+time+" milliseconds...");
Thread.sleep(time);
return "We finish on time!";
}
}
We are going to simulate a task that takes time by grabbing a random integer and then using it to sleep the thread for that time. Instead of String you could return any object you define in the generic type of the Callable interface.
Now we are going to execute that call:
ExecutorService executorService = Executors.newSingleThreadExecutor();
FutureTask <String>futureTask = new FutureTask<String>(new DummyCallback());
executorService.submit(futureTask);
String result = null;
try {
result = futureTask.get(50, TimeUnit.MILLISECONDS);
} catch (InterruptedException|ExecutionException|TimeoutException e) {
result = e.getClass().toString();
}
log.info(result);
We are getting an ExecutorService using the Executors newSingleThreadExecutor() method, that gives us an ExecutorService for a single thread, in this example is all we need.
Then we use a FutureTask to submit and get the result of the ExecutorService, in this case, we are giving the task a 50 milliseconds timeout.
When using this in a real world situation, remember this, the ExecutionException will wrap any exception thrown inside the callable task, the TimeoutException is going to be thrown if the callable task doesn’t complete on the time we set, and finally, the InterruptedException will be thrown if something interrupts the task being called. Also keep in my mind that you may need to shutdown any resources that you might have opened inside the callable.
This are sample outputs of the code above:
waiting for: 21 milliseconds…
We finish on time!waiting for: 58 milliseconds…
class java.util.concurrent.TimeoutException


