java timertask在一段时间后超时

ifsvaxew  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(587)

我有一个定时任务,它定期运行,但有时会卡住(不会失败或出现任何异常)。
因此,此任务的下一个迭代不会开始,因为上一个迭代被卡住了。
我希望任务:
一段时间后超时(以便可以开始下一次迭代)。
或者下一个迭代开始,即使上一个正在运行,这将强制取消上一个正在运行的任务。
下面是我的代码:

  1. private static Timer timer = new Timer();
  2. private static TimerTask timerTask = new TimerTask() {
  3. @Override
  4. public void run() {
  5. try{
  6. aSeparateMethodWhichGetsStuckOccasionally();
  7. }catch (Exception exception){
  8. logger.info(">>> Exception : " + exception);
  9. }
  10. }
  11. };
  12. public static void scheduleTask() {
  13. initialDelay = 600000;
  14. gap = 600000;
  15. timer.scheduleAtFixedRate(timerTask, initialDelay, gap);
  16. }
lsmd5eda

lsmd5eda1#

首先,你必须写作 aSeparateMethodWhichGetsStuckOccasionally() 这样它就能对中断做出正确的React。中断是停止许多操作的唯一方法。
如果这种方法很流行的话 InterruptedException ,完全删除try/catch,然后添加 throws InterruptedException 方法声明。如果该方法包含 catch (Exception) 子句,则必须检查 InterruptedException 并在这种情况下终止,或者更好,将子句更改为只捕获您绝对需要捕获的异常,而不包括interruptedexception(吸引人的 Exception 是个坏习惯。大多数未经检查的异常都会暴露程序员的错误,这些错误应该被纠正而不是隐藏。nullpointerexception和indexoutofboundsexception就是此类异常的示例。)
这将使中断方法成为可能。然后可以使用executorservice.invokeall对其强制执行超时:

  1. private static final ExecutorService executor =
  2. Executors.newSingleThreadExecutor();
  3. public static TimerTask timerTask = new TimerTask() {
  4. @Override
  5. public void run() {
  6. try {
  7. Callable<Void> subtask = () -> {
  8. aSeparateMethodWhichGetsStuckOccasionally();
  9. return null;
  10. };
  11. List<Future<Void>> futures =
  12. executor.invokeAll(Collections.singleton(subtask),
  13. gap, TimeUnit.MILLISECONDS);
  14. Future<?> future = futures.get(0);
  15. if (!future.isCancelled()) {
  16. // Check if subtask threw an exception.
  17. future.get();
  18. }
  19. } catch (Exception exception) {
  20. logger.log(Level.INFO, ">>> Exception: " + exception, exception);
  21. }
  22. }
  23. };
展开查看全部

相关问题