开发者社区> 问答> 正文

java自带的ScheduledExecutorService定时任务正常执行一?400报错

目前我有用java自带的ScheduledExecutorService线程任务做定时调度功能,我开启了足够多的线程数,比如开了300,实际上用到的只有50个。

我用的是newScheduledThreadPool这种方法做周期性定时任务的,目前发现运行了一段时间都正常,过了几天后,有些定时任务会莫名其妙的不执行,也不报错。比如代码块:

       //开启定时对应数量的任务线程池
        ScheduledExecutorService s = Executors.newScheduledThreadPool(300);
        //高频率定时任务--------------------------------------------------start

        //1分钟执行
        s.scheduleAtFixedRate(new Test1(),0,60000,TimeUnit.MILLISECONDS);

        s.scheduleAtFixedRate(new Test2(),0,60000,TimeUnit.MILLISECONDS);

        s.scheduleAtFixedRate(new Test3(),0,60000,TimeUnit.MILLISECONDS);

然后执行几天正常后,某一天发现只有1仍然定时1分钟执行,但是2和3任务都没执行,也不报错。我知道定时任务里面如果有异常会导致后续不执行,所以我已经在代码里面做了try ... catch的处理了。

public class Test2Service implements Runnable{    
    @Override
    public void run() {
        try{//必须加try-catch防止方法里面异常后下次定时任务不执行
            jobStart();
        }catch (Exception e) {   
            e.printStackTrace();   
            logger.error("定时任务处理异常");
        } 
    }
    
    //定时任务开始
    public void jobStart(){
        //获取当前时分做判断
        Date now = new Date(); 
        SimpleDateFormat dateFormat = new SimpleDateFormat("HHmm");
        String currentMin = dateFormat.format(now);
        dateFormat = new SimpleDateFormat("YYYYMMdd");
        String currentDay = dateFormat.format(now);
        if(QuoteBaseService.useFullTime(currentMin)&&QuoteBaseService.isTradeDay(currentDay)){//有效时间里面才1分钟执行,比如周末都不执行
            hotProfileZstMin();
        }
    }

请问有什么可能会导致这样的情况呢,而且我只要当天在服务器kill掉程序的进程后,重新启动服务就都正常了。。。

当然日志里面有部分定时任务报错了,但是我也都做了异常处理(防止不重新执行)的,目前不知道是怎么回事

展开
收起
爱吃鱼的程序员 2020-06-08 17:26:17 1295 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    会不会发生了锁表?

    应该不会,因为在方法的一开始就会有打印开始任务的记录,如果是锁表,那应该会有进入方法的日志才对,而且目前操作的是mongodb

    首先不要为所有任务配置一个线程池,未每一个任务配置一个线程池(每个线程池有自己的任务队列)。线程数量不要过高

    ScheduledExecutorServices1=Executors.newScheduledThreadPool(10);

    ScheduledExecutorServices2=Executors.newScheduledThreadPool(10);

    ScheduledExecutorServices3=Executors.newScheduledThreadPool(10);

    我认为你的问题是线程池s内部队列阻塞了,即消费能力太差,1min钟内无法处理完毕3个任务

    哈哈回复 @混元归一:嗯,先调整试试,消费能力之前没有考虑到,确实不少任务都超过了原先预测的时间回复 @594zzb:建议先调整下,观察下,看看还会不会出问题回复 @594zzb:不能一概而论,我个人觉得是因为你的消费太慢造成的。如果是消费非常快的任务,你可以一个线程池,线程数量实际上一个应用(或者一个JVM)是有限制的。经验值:非IO密集型线程数=CPU+1,IO密集型线程数可以大一些=3*cpu(个人经验)意思是假如我这边有50个任务,分别配置50个线程池,然后里面的数量可以设置为1或者稍微多点但又不大的值对吗

    线程池中线程的个数是需要根据CPU的数量和实际的代码执行情况决定的Runtime.getAvailableProcessers*loadfactor,感觉上面一个回复挺有道理的 不知道题主有没有解决呢?

    2020-06-08 17:26:29
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载