Java timeout

In the java class, I have a method that sometimes takes a long time to execute. Perhaps this hangs in the method thread. I want the method to not run at a specific time, the program must exit this method and continue with the rest of the thread.

Please let me know if there is a way to handle this situation.

+5
java
source share
4 answers

To achieve this, you must use threads. Threads are not harmful. Example below: run a piece of code for 10 seconds, and then complete it.

public class Test { public static void main(String args[]) throws InterruptedException { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("0"); method(); } }); thread.start(); long endTimeMillis = System.currentTimeMillis() + 10000; while (thread.isAlive()) { if (System.currentTimeMillis() > endTimeMillis) { System.out.println("1"); break; } try { System.out.println("2"); Thread.sleep(500); } catch (InterruptedException t) {} } } static void method() { long endTimeMillis = System.currentTimeMillis() + 10000; while (true) { // method logic System.out.println("3"); if (System.currentTimeMillis() > endTimeMillis) { // do some clean-up System.out.println("4"); return; } } } } 
+7
source share

Run the method in another thread, you can terminate the thread at any time.

+1
source share

Based on the snipplet above, I tried to create an illustrious spring bean.

Such an executor runs a limited limited time duration in a limited execution time. If the job ends within its duration, the caller continues to perform normally.

If limitRuntimeTask could not be completed at certain runtimeInMs, the caller will receive a thread execution. If a temporary table has been defined, it will be executed before returning to the caller.

 public class LimitedRuntimeExecutorImpl { public void runTaskInLessThanGivenMs(int runtimeInMs, final Callable limitedRuntimeTask, final Callable timeBreachedTask) { Thread thread = new Thread(new Runnable() { @Override public void run() { try { LOGGER.info("Started limitedRuntimeTask"); limitedRuntimeTask.call(); LOGGER.info("Finished limitedRuntimeTask in time"); } catch (Exception e) { LOGGER.error("LimitedRuntimeTask exception", e); } } }); thread.start(); long endTimeMillis = System.currentTimeMillis() + runtimeInMs; while (thread.isAlive()) { if (System.currentTimeMillis() > endTimeMillis) { LOGGER.warn("LmitedRuntimeTask did not finish in time (" + runtimeInMs + ")ms. It will run in vain."); if(timeBreachedTask != null ){ try { LOGGER.info("Executing timeBreachedTask"); timeBreachedTask.call(); LOGGER.info("Finished timeBreachedTask"); } catch (Exception e) { LOGGER.error("timeBreachedTask exception", e); } } return; } try { Thread.sleep(10); } catch (InterruptedException t) {} } } 

}

0
source share

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); } } 
0
source share

All Articles