scheduleAtFixedRate()踩的坑

公司有个定时任务,跑了10+天挂了,看日志没有任何的错误信息,查找一番发现问题所在,记录一下。

一直以为scheduleAtFixedRate()和scheduleWithFixedDelay()这两个方法的区别是,scheduleWithFixedDelay()是延迟任务,scheduleAtFixedRate()是定时任务:

        ScheduledExecutorService services = Executors.newScheduledThreadPool(2);

        //scheduleWithFixedDelay
        services.scheduleWithFixedDelay(new MyRunnable(), 10, 2 * 60, TimeUnit.SECONDS);

        //scheduleAtFixedRate
        services.scheduleAtFixedRate(new MyRunnable(), 10, 2 * 60, TimeUnit.SECONDS);

我的理解是:scheduleWithFixedDelay()定时任务会在10秒之后开始第一次执行,等到上一次任务执行完后,延迟120秒执行第二个任务;scheduleAtFixedRate()定时任务会在10秒后执行,等到120秒后,不管上一次任务是否执行完成,直接开始执行第二次任务。(错误的理解


scheduleAtFixedRate 与 scheduleWithFixedDelay 的区别,看了大佬的博客才知道,我的理解有点问题:

scheduleAtFixedRate ,是以上一个任务开始的时间计时,120秒过去后,检测上一个任务是否执行完毕,如果上一个任务执行完毕,则当前任务立即执行,如果上一个任务没有执行完毕,则需要等上一个任务执行完毕后立即执行。

scheduleWithFixedDelay,是以上一个任务结束时开始计时,120秒过去后,立即执行。


加上另外一个大佬的博客,找到了问题所在,Java定时线程池停止超时任务。博客里面提到了:

关于定时线程池,好多人认为设置好频率(比如1Min),它会按照这个间隔按部就班的工作。但是,如果其中一次调度任务卡住的话,不仅这次调度失败,而且整个线程池也会停在这次调度上。


回头看了下代码,整个定时任务完全没有try...catch...异常,而最后一次连接数据库时出现了某种异常,导致以后的调度任务全部失效(上一任务没有完成),最后导致整个定时任务死掉了。。。

知道了原因,解决起来就好办了,在线程的run()方法里面用try...catch...fianlly...包围

    @Override
    public void run() {
        try {
            //初始化数据库
            Jedis bns3Redis= MyJedisPool.getRedis();
            if (null == bns3Redis) {
                logger.error("init jedis failed");
            }

           //do sth
            startHandle(bns3Redis);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("exception:" + e.getMessage());
        } finally {
            if (null != bns3Redis)
                try {
                    bns3Redis.close();
                } catch (Exception e) {
                    logger.error("close redis exception:" + e.getMessage());
                    bns3Redis = null;
                }
        }

        logger.info("=====updateTime======" + updateTime);
    }

 

  • 20
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
用Java编写银行业务调度系统,附主类: package com.isoftstons.interview.bank; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Mainlass { public Mainlass() { } public static void main(String[] args) { ServiceWindow vipWindow; for(int i = 1; i < 5; ++i) { vipWindow = new ServiceWindow(); vipWindow.setWindowId(i); vipWindow.start(); } ServiceWindow expressWindow = new ServiceWindow(); expressWindow.setType(CustomerType.EXPRESS); expressWindow.start(); vipWindow = new ServiceWindow(); vipWindow.setType(CustomerType.VIP); vipWindow.start(); Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { public void run() { Integer number = NumberMachine.getInstance().getCommonManager().generateNewManager(); System.out.println(number + "号普通客户等待服务"); } }, 0L, (long)Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS); Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { public void run() { Integer number = NumberMachine.getInstance().getExpressManager().generateNewManager(); System.out.println(number + "号快速客户等待服务"); } }, 0L, (long)(Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6), TimeUnit.SECONDS); Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { public void run() { Integer number = NumberMachine.getInstance().getVipManager().generateNewManager(); System.out.println(number + "号VIP客户等待服务"); } }, 0L, (long)(Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2), TimeUnit.SECONDS); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值