July 29, 2005
Java 5: Make an arbitrary code block time out
The Commons-HttpClient API does provide methods for asserting timeouts on HTTP connections, but those methods appear to have no effect when you encounter a socket timeout or some other OS-level blocking. I needed a way to say "Fetch me this resource, as long as it doesn't take you more than n milliseconds, and I mean it!" Here's what I came up with.
Java 5's util.concurrent provides the necessary ingredients, while generic static methods keep the kitchen clean.
private static final ExecutorService THREADPOOL
= Executors.newCachedThreadPool();
private static <T> T call(Callable<T> c, long timeout, TimeUnit timeUnit)
throws InterruptedException, ExecutionException, TimeoutException
{
FutureTask<T> t = new FutureTask<T>(c);
THREADPOOL.execute(t);
return t.get(timeout, timeUnit);
}
Now, if you wanted to hatch an Egg, but only if you could get it in fewer than 2 seconds, you'd
try {
Egg egg = call(new Callable<Egg>() {
public Egg call() throws Exception
{
// Constructing an egg could take a while
return new Egg(Bird.ROC);
}, 2, TimeUnit.SECONDS);
scramble(egg);
} catch (TimeoutException e) {
System.err.println("You'd better order out.");
}
Comments
