令仔学多线程系列----每天定点执行指定任务

Posted 令仔很忙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了令仔学多线程系列----每天定点执行指定任务相关的知识,希望对你有一定的参考价值。


/**
 * 定点去发起重搜类-21点
 * Created by ling.zhang on 2017/3/1.
 */
@Component
public class AirChangeTimerManage extends TimerTask 
    private static final Logger logger= LoggerFactory.getLogger(AirChangeTimerManage.class);

    @Autowired
    PolicyRedisManage redisManage;


    //时间间隔  ms
    private static final long PERIOD_DAY = 24 * 60 * 60 * 1000;

    public AirChangeOrderLoadManage()
        Calendar calendar=Calendar.getInstance();

        /*** 定制每日4:00执行方法 ***/
        calendar.set(Calendar.HOUR_OF_DAY,4);
        calendar.set(Calendar.MINUTE,00);
        calendar.set(Calendar.SECOND,00);

        Date date=calendar.getTime();  //第一次执行定时任务的时间

        //如果第一次执行定时任务的时间  小于 当前时间
        //此时要在第一次执行定时任务的时间加一天,以便次任务在下个时间点执行,如果不加一天,任务会立即执行。
        if (date.before(new Date()))
            date=this.addDay(date,1);
        

        Timer timer=new Timer();
        //安排指定的任务在指定的时间开始进行重复的固定延迟执行。
        timer.schedule(this,date,PERIOD_DAY);
    

    // 增加或减少天数
    public Date addDay(Date date, int num) 
        Calendar startDT = Calendar.getInstance();
        startDT.setTime(date);
        startDT.add(Calendar.DAY_OF_MONTH, num);
        return startDT.getTime();

    



    @Override
    public void run()
        try
            //相关任务
        catch (Exception e)
            logger.error("airchange timer error ",e);
        
    

    需要注意的一个地方,就是在AirChangeTimerManage 类中,我是每天4点定时执行任务,但是如果我在4点之后进行了重启或者发布,启动之后这个任务就会立即启动执行,这样并不是我想要的,为了,避免这种情况发生,只能判断一下,如果发布或重启服务的时间晚于定时执行任务的时间,就在此基础上加一天。
    

扩展

    
    上面的这种方式还是有些局限的,如果有多个定时任务,那每个类中都要加这些代码。因为我在这用的是this。只执行当前类。

timer.schedule(this,date,PERIOD_DAY);

    所以这样还是有些坑的,当然这也得看具体的情况。可以是这样的

Timer timer = new Timer();
24

25
  AirChangeTimerManage task = new AirChangeTimerManage();
26
  //安排指定的任务在指定的时间开始进行重复的固定延迟执行。
27
  timer.schedule(task,date,PERIOD_DAY);

    但是在AirChangeTimerManage类里面,有下面这些代码:

 @Value("$airchangeopen")
    String airChangeOpen;

    @Autowired
    OTAOrderFlightInfoDao flightInfoDao;

    @Autowired
    ReportDetailDao reportDetailDao;

    @Autowired
    PolicyRedisManage redisManage;

    如果用new的话,这些会启动不起来的。当然如果你的任务中如果只涉及到了一些计算之类的,完全可以用另外new的方式。扩展性挺好的。就是配置一个监听器来监听定时任务。

public class AirChangeTimerManage extends TimerTask 
 private static Logger log = Logger.getLogger(NFDFlightDataTimerTask.class);

 @Override
 public void run() 
  try 
   //在这里写你要执行的内容
   catch (Exception e) 
   log.info("-------------解析信息发生异常--------------");
  
 


public class AirChangeListener implements ServletContextListener 

 public void contextInitialized(ServletContextEvent event) 
  new AirChangeTimerManage();
 

 public void contextDestroyed(ServletContextEvent event) 
 

    然后再web.xml中配置监听器

<listener>

 <listener-class>

  com.listener.NFDFlightDataTaskListener

 </listener-class>

</listener>

    这样的话,多个定时任务就不会出现那么多的重复代码了。
    如果有什么不足之处,还望各位同志们多多指正。

以上是关于令仔学多线程系列----每天定点执行指定任务的主要内容,如果未能解决你的问题,请参考以下文章

令仔学多线程系列----自定义Queue队列

令仔学Redis----单线程架构

令仔学Redis----单线程架构

令仔学MySql系列----explain详解

令仔学Redis----浅析Redis存储数据时格式的设计

quartz求助:每天定点执行一次,该怎么做?