• 使用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,即使捕获了能做的事也有限,但至少可以保证定时任务能继续,并且在日志里留下痕迹方便排查。

  • 相关阅读:
    博客园添加侧边栏小插件并更改css样式
    ubuntu14.04环境下利用docker搭建solrCloud集群
    使用Grunt 插件打包Electron Windows应用
    使用Squirrel创建基于Electron开发的Windows 应用安装包
    Electron实战:创建ELectron开发的window应用安装包
    6、创建-查看-复制-删除-文件和文件夹相关命令
    5、Linux 系统基本文件管理
    3、Linux 获取帮助的方法-关机命令-7个系统启动级别
    2 、Linux基本命令-ls-pwd-cd-date-hwclock
    1 、Linux-Rhel6终端介绍-Shell提示符
  • 原文地址:https://www.cnblogs.com/BoyTNT/p/13890540.html
Copyright © 2020-2023  润新知