I feel the approach in the accepted answer is a bit outdated. With Java8, this can be made much simpler.
Say you have a method
MyResult conjureResult(String param) throws MyException { ... }
then you can do it (keep reading, this is just to show the approach):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor(); MyResult conjureResultWithTimeout(String param, int timeoutMs) throws Exception { Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param)); return future.get(timeoutMs, TimeUnit.MILLISECONDS); }
of course, throwing an Exception is bad, here is the correct extended version with proper error handling, but I suggest you carefully study it, you might want to do something different (logging, returning a timeout to an extended result, etc.):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor(); MyResult conjureResultWithTimeout(String param, int timeoutMs) throws MyException { Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param)); try { return future.get(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { //something interrupted, probably your service is shutting down Thread.currentThread().interrupt(); throw new RuntimeException(e); } catch (ExecutionException e) { //error happened while executing conjureResult() - handle it if (e.getCause() instanceof MyException) { throw (MyException)e.getCause(); } else { throw new RuntimeException(e); } } catch (TimeoutException e) { //timeout expired, you may want to do something else here throw new RuntimeException(e); } }
Alex Pakka
source share