先上代碼:
scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// do some download task
}
}, 5, 60, TimeUnit.SECONDS);
問題現(xiàn)象
上面代碼的業(yè)務(wù)邏輯是本地起一個定時任務(wù)蜓氨,定期的從服務(wù)器上下載一些東西筷频。但是今天在檢查日志文件時筋粗,發(fā)現(xiàn)這個定時任務(wù)沒有周期調(diào)度集晚,最后一次調(diào)度的時候只是打印了要從服務(wù)器上下載東西的提示信息,并沒有結(jié)果日志蜓谋。初步懷疑是不是服務(wù)器出現(xiàn)問題了沒有響應(yīng)梦皮,導(dǎo)致下載線程一直卡住。后來加了超時時間后孤澎,測試發(fā)現(xiàn)日志依然是卡在任務(wù)開始的時候届氢,沒有結(jié)果日志。
問題原因
跟蹤代碼后發(fā)現(xiàn)并非是線程卡住覆旭,而是調(diào)度的Runnable代碼出現(xiàn)異常退子,而該異常被ScheduledFuture吞了岖妄,沒有提示也沒有打印日志。
通過查看scheduleAtFixedRate的jdk文檔寂祥,有一句如下:
If any execution of the task encounters an exception, subsequent executions are suppressed.
如果在任務(wù)的執(zhí)行中遇到異常荐虐,后續(xù)執(zhí)行被取消。
解決措施
在調(diào)度的Runnable的run方法中把業(yè)務(wù)代碼try-catch丸凭,最好是catch Throwable福扬,防止出現(xiàn)異常后調(diào)度任務(wù)終止。
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
// do something
} catch (Throwable e) {
// do catch exception
}
}
}, 5, 60, TimeUnit.SECONDS);