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

时间:2022-06-10 21:45:41

/**
* 定点去发起重搜类-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>

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