zoukankan      html  css  js  c++  java
  • 使用ScheduledExecutorService执行定时任务时一定要注意各种异常捕获

    近期一个项目有个定时任务阻塞住了,从日志里看没有任何异常产生,但就是定时不再执行了,进程还在,jstack看了下线程处于WAIT状态,但就是不再定时触发。于是拿代码分析了一下,代码原理很简单,拿ScheduledExecutorService.scheduleWithFixedDelay设定的定时任务,简化后类似这样:

    public class Application {
        private static ScheduledExecutorService timer = Executors.newScheduledThreadPool(2);
        public static void main(String[] args) {
            timer.scheduleWithFixedDelay(() -> {
                try {
                    //此处执行任务
                } catch(Exception ex) {
                    System.out.println(ex.getMessage());
                }
            }, 0, 1, TimeUnit.SECONDS);
        }
    }
    

    一般定时任务挂了,第一考虑的就是任务线程异常了,因为javadoc里关于scheduleWithFixedDelay有这样的警告:

    当有异常产生时,后续定时任务就停掉了。但是代码里已经考虑了异常情况,做了try/catch,并且没有输出错误日志,只好修改代码尝试跟踪下线程执行结果:

    public class Application {
        private static ScheduledExecutorService timer = Executors.newScheduledThreadPool(2);
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            ScheduledFuture<?> handle = timer.scheduleWithFixedDelay(() -> {
                try {
                    //此处执行任务
                } catch(Exception ex) {
                    System.out.println(ex.getMessage());
                }
            }, 0, 1, TimeUnit.SECONDS);
    
            handle.get();    //如果线程执行异常,此处会抛出
        }
    }
    

    用ScheduledFuture跟踪,上面的测试程序当然不会报错,但在实际环境里打印了下面的异常:

    Exception in thread "pool-1-thread-1" java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError

    这下搞清楚了,因为-Xmx参数不合理导致线程在处理某个大数据时抛出OOM,这个错误没有被上面的try/catch捕获,导致定时任务挂掉。因此使用ScheduledExecutorService时一定要注意考虑各种可能的异常,不过对于OOM,即使捕获了能做的事也有限,但至少可以保证定时任务能继续,并且在日志里留下痕迹方便排查。

  • 相关阅读:
    openwrt
    第37章 socket编程 之练习:实现简单的web服务器
    Unix domain socket IPC
    String题目解析1
    this()与super()
    if当中是赋值怎么办
    编译时检查错误有哪些
    int与Integer
    log4j日志级别怎么搞
    数据库标准八步每一步中的作用
  • 原文地址:https://www.cnblogs.com/BoyTNT/p/13890540.html
Copyright © 2011-2022 走看看