項目中有個功能需要判斷某線程在指定時間內是否執行完畢,FutureTask正好可以實現此功能,FutureTask有個get(long timeout, TimeUnit unit)
方法,可以指定超時時間,若超時會拋出TimeoutException。
被調方實現:
public <T> void startTimer(Callable<T> task, long timeout) throws TimeoutException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
FutureTask<T> futureTask = (FutureTask<T>) executorService.submit(task);
executorService.execute(futureTask);
try {
futureTask.get(timeout, TimeUnit.SECONDS);
} catch (TimeoutException e) {
throw e;
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new TimeoutException();
} finally {
executorService.shutdown();
}
}
調用時需要傳入Callable,調用方:
// 3. 設置定時器: 若限時內所有網關響應狀態未清除,則拋出異常
try {
timerUtil.startTimer(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
// 循環判斷網關響應狀態
while (true) {
if (!msgResponseStatusService.checkGWResponseStatus(sessionId)) break;
}
// 若響應狀態記錄已不存在則返回
return true;
}
}, timeout);
} catch (TimeoutException e) {
logger.info("response from gateway is timeout: {} seconds", timeout);
調用時實現Callable接口中的Call方法即可。