您的位置:首页 > 其它

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

2017-03-06 10:13 387 查看
/**
* 定点去发起重搜类-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>


这样的话,多个定时任务就不会出现那么多的重复代码了。

如果有什么不足之处,还望各位同志们多多指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 定时任务