Standard Java template for timeout wrapping around an error process

I use a third-party function (say, runThird ()), which tends to loop endlessly and has no built-in timeout. However, I can kill it (killThird ()). Is there a way to do this (i.e., some concurrency construct)?

Here is my attempt:

java.lang.Thread thread = new Thread(new Runnable(){ @Override public void run(){ try { Thread.sleep(TIMEOUT); } catch (java.lang.InterruptedException e){ return; } killThird(); } }); thread.start(); RunThirdResult rtr = runThird(); if (thread != null){ thread.interrupt(); } 

But I'm not sure I like the overhead of creating a thread, using sleep, and being able to interrupt a thread if runThird () returns.

+4
source share
3 answers

Suppose runThird() retuns Integer ...

 // ... in your class ... private ExecutorService executor = Executors.newCachedThreadPool(); //... then somewhere, where you want to call runThird() Future<Integer> handle = executor.submit( new Callable<Integer>(){ @Override Integer call(){ return runThird(); // Assume you made it available here ... } } Integer result; try{ result = handle.get(TIMEOUT,UNIT); // TIMEOUT and UNIT declared somewhere above ... } catch(TimeoutException ex) { killThird(); // HANDLE result not being set! } // ... use result. 
+3
source

For this, I would use a ScheduledExecutorService. Schedule him to be killed.

 volatile RunThirdResult rtr; ScheduledExecutorService service = Executors.newScheduledThreadPool(1); service.schedule(new Runnable(){ public void run(){ if(rtr == null) killThird(); } }, TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS); RunThirdResult rtr = runThird(); 
+2
source

Something like that? The most interesting part is StoppableWrapper#stop() , because graceful undoing is a difficult thing, and there is no general approach for all cases. Once you need to clean the file system, at another time, close the network connection, etc. In your example, you just call interrupt() , so I accepted runThird() differences that break, and will take care to clean things up behind me.

 class Sample { final ExecutorService tasksExecutor = Executors.newCachedThreadPool(); class StoppableWrapper implements Runnable { private final Runnable task; private final CountDownLatch executed; StoppableWrapper(Runnable task, CountDownLatch executed) { this.task = task; this.executed = executed; } void stop() { // eg Thread.currentThread().interrupt() } @Override public void run() { task.run(); executed.countDown(); } } public void scheduleTimingOutTaskExecution(final long timeout) { final CountDownLatch executed = new CountDownLatch(1); final StoppableWrapper command = new StoppableWrapper(new RunThirdInstance(), executed); tasksExecutor.execute(command); tasksExecutor.execute(new Runnable() { @Override public void run() { try { if (!executed.await(timeout, TimeUnit.MILLISECONDS)) { command.stop(); // additionally, you can make stop() return boolean after time-out as well and handle failure } } catch (InterruptedException e) { // handle stopper exception here } } }); } } 
0
source

Source: https://habr.com/ru/post/1485779/


All Articles