Java定时任务功能实现

时间:2022-08-12 07:51:02
小弟想实现这样一个定时任务功能:从队列中取出一个任务(通知商户发货任务)执行,如果执行失败则会在后续的{ 8S, 30S, 60S, 300S, 3600S,7200S}重复执行,其中任何一次执行成功则不需要再执行后续的。

调研了下java几个定时器框架,quartz适合固定周期如每天定时执行的任务,不太适合这个场景,其它的如Timer和ScheduledExecutor可以实现,但需要自己去控制逻辑指定下次执行的时间,想问下 第一个问题:有没有适合这种定时场景的框架可用呢?

还有个问题是,如果采用quartz或ScheduledExecutor的话,任务有可能执行失败,如果某个商家通知接口暂时宕机,会造成大量的通知发货任务处于定时任务状态,是不是很消耗性能, 第二个问题:有什么办法来控制这种异常情况?
我的想法是如果真没有较好的控制方法,是不是可以牺牲点时间的准确性,用类似扫描器的功能,定时扫描队列,取出一批任务,如果到达执行时间了就执行,没有到达时间就放回队列,这样实现有什么需要考虑的吗?


谢谢!

5 个解决方案

#1


直接线程休眠实现?

#2


我觉得用消息队列比较适合这个场景,如果处理失败了,就抛出异常,并放回队列,成功了就不放回就i行了

#3


import java.io.IOException;
import java.util.Date;
import java.util.Timer;


public class TimeTimer {

public  void run(){     
        Timer timer = new Timer();     
        timer.schedule(new MyTask(), 1000, 1000);//在1秒后执行此任务,每次间隔1秒执行一次,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.     
        while(true){//这个是用来停止此任务的,否则就一直循环执行此任务     
            try{     
                int in = System.in.read();    
                if(in == 's'){     
                    timer.cancel();//使用这个方法退出任务     
                    break;  
                }     
            } catch (IOException e){     
                // TODO Auto-generated catch block     
                e.printStackTrace();     
            }     
        }     
    }    
      
    static class MyTask extends java.util.TimerTask{      
        @SuppressWarnings("deprecation")
public void run(){     
         System.out.println("*****定时开始*****");
            System.out.println(new Date().toLocaleString());     
        }     
    }    
}

#4


引用 2 楼 sunli880127 的回复:
我觉得用消息队列比较适合这个场景,如果处理失败了,就抛出异常,并放回队列,成功了就不放回就i行了



消息队列可以。。。
而且淘宝还有开源的消息队列通知,,并且可以保证消息的一致性。。可以看看。。

#5


嗯 这个可以 之前就做过的项目中就做过类似的功能。
引用 3 楼 yulei2008_ 的回复:
import java.io.IOException;
import java.util.Date;
import java.util.Timer;


public class TimeTimer {

public  void run(){     
        Timer timer = new Timer();     
        timer.schedule(new MyTask(), 1000, 1000);//在1秒后执行此任务,每次间隔1秒执行一次,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.     
        while(true){//这个是用来停止此任务的,否则就一直循环执行此任务     
            try{     
                int in = System.in.read();    
                if(in == 's'){     
                    timer.cancel();//使用这个方法退出任务     
                    break;  
                }     
            } catch (IOException e){     
                // TODO Auto-generated catch block     
                e.printStackTrace();     
            }     
        }     
    }    
      
    static class MyTask extends java.util.TimerTask{      
        @SuppressWarnings("deprecation")
public void run(){     
         System.out.println("*****定时开始*****");
            System.out.println(new Date().toLocaleString());     
        }     
    }    
}

#1


直接线程休眠实现?

#2


我觉得用消息队列比较适合这个场景,如果处理失败了,就抛出异常,并放回队列,成功了就不放回就i行了

#3


import java.io.IOException;
import java.util.Date;
import java.util.Timer;


public class TimeTimer {

public  void run(){     
        Timer timer = new Timer();     
        timer.schedule(new MyTask(), 1000, 1000);//在1秒后执行此任务,每次间隔1秒执行一次,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.     
        while(true){//这个是用来停止此任务的,否则就一直循环执行此任务     
            try{     
                int in = System.in.read();    
                if(in == 's'){     
                    timer.cancel();//使用这个方法退出任务     
                    break;  
                }     
            } catch (IOException e){     
                // TODO Auto-generated catch block     
                e.printStackTrace();     
            }     
        }     
    }    
      
    static class MyTask extends java.util.TimerTask{      
        @SuppressWarnings("deprecation")
public void run(){     
         System.out.println("*****定时开始*****");
            System.out.println(new Date().toLocaleString());     
        }     
    }    
}

#4


引用 2 楼 sunli880127 的回复:
我觉得用消息队列比较适合这个场景,如果处理失败了,就抛出异常,并放回队列,成功了就不放回就i行了



消息队列可以。。。
而且淘宝还有开源的消息队列通知,,并且可以保证消息的一致性。。可以看看。。

#5


嗯 这个可以 之前就做过的项目中就做过类似的功能。
引用 3 楼 yulei2008_ 的回复:
import java.io.IOException;
import java.util.Date;
import java.util.Timer;


public class TimeTimer {

public  void run(){     
        Timer timer = new Timer();     
        timer.schedule(new MyTask(), 1000, 1000);//在1秒后执行此任务,每次间隔1秒执行一次,如果传递一个Data参数,就可以在某个固定的时间执行这个任务.     
        while(true){//这个是用来停止此任务的,否则就一直循环执行此任务     
            try{     
                int in = System.in.read();    
                if(in == 's'){     
                    timer.cancel();//使用这个方法退出任务     
                    break;  
                }     
            } catch (IOException e){     
                // TODO Auto-generated catch block     
                e.printStackTrace();     
            }     
        }     
    }    
      
    static class MyTask extends java.util.TimerTask{      
        @SuppressWarnings("deprecation")
public void run(){     
         System.out.println("*****定时开始*****");
            System.out.println(new Date().toLocaleString());     
        }     
    }    
}