Created
August 11, 2016 06:44
-
-
Save henrrich/e89a14446196cfcb11201f1df5adc5c9 to your computer and use it in GitHub Desktop.
Running task in seperated thread using executor framework and handles timeout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.util.concurrent.*; | |
/** | |
* Created by hehuan on 10/08/2016. | |
* | |
* This class uses a single thread to execute the task assigned to it and wait for the result. | |
* User can specify the total timeout for finishing task as well as time out for each individual task iteration. | |
* If a task times out, but the total timeout has not been reached, this class will retry the task again in a new thread. | |
*/ | |
public class WaitUtil { | |
private static Logger logger = LoggerFactory.getLogger(WaitUtil.class); | |
private ExecutorService executorService; | |
private long totalTimeout; | |
private long taskTimeout; | |
private Callable task; | |
/** | |
* Constructor | |
* | |
* @param totalTimeout long total timeout in seconds | |
* @param taskTimeout long timeout for each task computation | |
* @param task Callable task reference | |
*/ | |
public WaitUtil(long totalTimeout, long taskTimeout, Callable task) { | |
this.totalTimeout = totalTimeout; | |
this.taskTimeout = taskTimeout; | |
this.task = task; | |
this.executorService = Executors.newSingleThreadExecutor(); | |
} | |
/** | |
* This method will execute the task in a thread and wait for its result. | |
* If individual task computation times out, the method will retry the task in a new thread until total timeout is reached. | |
* | |
* @return Object task computation result | |
* @throws TimeoutException throw TimeoutException if total timeout is reached | |
*/ | |
public Object waitForTaskDone() throws TimeoutException { | |
long expectedTimeout = System.currentTimeMillis() + totalTimeout * 1000L; | |
while (true) { | |
if (System.currentTimeMillis() < expectedTimeout) { | |
logger.info("Start to execute task " + task.getClass() + " in a seperate thread!"); | |
Future future = executorService.submit(task); | |
try { | |
Object result = future.get(taskTimeout, TimeUnit.SECONDS); | |
close(); | |
return result; | |
} catch (Exception e) { | |
logger.warn("Timeout or failure to execute task " + task.getClass() + ": " + e.getMessage()); | |
future.cancel(true); | |
} | |
} else { | |
close(); | |
throw new TimeoutException("Failed to complete task " + task.getClass() + " within " + totalTimeout + " seconds!"); | |
} | |
} | |
} | |
private void close() { | |
if (!executorService.isShutdown()) { | |
executorService.shutdownNow(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment