我正在将任务安排为定期执行,例如1点之后,在特定时间说10:00 AM。我在Spring ScheduledExecutorTask中使用Java util TimerTask作为可运行的。
我要声明
之类的豆子private void declareAuditBackupBeans(DefaultListableBeanFactory beanFactory, boolean isSuiteServer) throws Exception{
try{
boolean isAuditBackupThreadOn = AuditUtil.isAuditBackupThreadOn();
if(logger.isDebugEnabled()){
logger.debug("AuditBackupThread is : " + isAuditBackupThreadOn);
}
if(!isAuditBackupThreadOn) {
if(logger.isDebugEnabled()){
logger.debug("AuditBackupThread is off. Backup thread won't be started.");
}
return;
}
// set this to false while initializing. just in case it's been left dangling
AuditUtil.setIsBackupCurrentlyRunning(false);
logger.debug("Last successful backup time was : " + AuditUtil.getLastSuccessfulBackupTime());
AuditBackupTimerTask auditBackupTimerTask = new AuditBackupTimerTask();
AuditBackupScheduledTimerTask auditBackupScheduledTimerTask = new AuditBackupScheduledTimerTask();
auditBackupScheduledTimerTask.setDays(getAuditBackupDays());
auditBackupScheduledTimerTask.setAuditBackupDate(getAuditBackupDate());
auditBackupScheduledTimerTask.setRunnable(auditBackupTimerTask);
BeanDefinition beanDefinition = new RootBeanDefinition(AuditBackupScheduledTimerTask.class);
beanFactory.registerBeanDefinition("AuditBackupScheduledTimerTask", beanDefinition);
beanFactory.initializeBean(auditBackupScheduledTimerTask, "AuditBackupScheduledTimerTask");
ScheduledExecutorFactoryBean timerFactoryBean = new ScheduledExecutorFactoryBean();
timerFactoryBean.setDaemon(true);
List<ScheduledExecutorTask> scheduledTimerTasks = new ArrayList<ScheduledExecutorTask>();
scheduledTimerTasks.add(auditBackupScheduledTimerTask);
timerFactoryBean.setScheduledExecutorTasks(scheduledTimerTasks.toArray(new ScheduledExecutorTask[scheduledTimerTasks.size()]));
// Register the bean
beanDefinition = new RootBeanDefinition(ScheduledExecutorFactoryBean.class);
beanFactory.registerBeanDefinition("AuditBackupTimerFactoryBean", beanDefinition);
beanFactory.initializeBean(auditBackupScheduledTimerTask, "AuditBackupTimerFactoryBean");
timerFactoryBean.afterPropertiesSet();
auditBackupScheduledTimerTask.getPeriod();
if (logger.isDebugEnabled()) {
logger.debug("timerFactoryBean: " + timerFactoryBean);
}
}catch(Exception e)
{
logger.error("Error initializing backup thread on server. backup won't be started. " , e);
}
}
在执行timerFactoryBean.afterPropertiesSet();时; stmt-设置了延迟(AuditBackupScheduledTimerTask.getDelay()),它清楚地显示了下一个运行时间,如Feb 07 10:00 2019 1天和10:00的延迟时间,但是那时任务没有执行
ScheduledExecutorTask实现
public class AuditBackupScheduledTimerTask extends ScheduledExecutorTask {
private static final Logger LOG = Logger.getLogger(AuditBackupScheduledTimerTask.class);
private static final int HOURS_IN_DAYS = 24;
private static final int MINS_IN_HOURS = 60;
private static final int SECS_IN_MINS = 60;
private static final int MILLIS_IN_SECS = 1000;
private int days;
private int hour;
private int minute;
public void setAuditBackupDate(String auditBackupDate) throws Exception {
if(LOG.isTraceEnabled()) {
LOG.trace("Parsing the date for audit backup thread : " + auditBackupDate);
}
String[] hhmm = auditBackupDate.split(":");
Boolean isInvalidTime = Boolean.TRUE;
if(hhmm != null && hhmm.length == 2) {
// Parse an hour
String hh = hhmm[0];
if(StringUtils.isNumeric(hh) && Integer.valueOf(hh) >= 0 && Integer.valueOf(hh) <= 23) {
this.hour = new Integer(hh);
// Now parse the time...
String mm = hhmm[1];
if(StringUtils.isNumeric(mm) && Integer.valueOf(mm) >= 0 && Integer.valueOf(mm) <= 59) {
this.minute = new Integer(mm);
isInvalidTime= Boolean.FALSE;
if(LOG.isTraceEnabled()) {
LOG.trace("Hours and Minutes computed as : " + hour + " : " + minute);
}
}
}
}
LOG.debug("Is invalid time: " + isInvalidTime);
if(isInvalidTime) {
LOG.error("Enter the valid time value for configuration key 'auditBackupInTime'. The value should be in 'HH:MM' format and within the valid time range...");
throw new Exception("Incorrect value for property 'Archive start time' is given...");
}
}
public long getDelay () {
long delay = -1;
long lastRun = getLastRun();
Calendar nextRun=Calendar.getInstance();
if(LOG.isDebugEnabled()) {
LOG.debug("Last run information is : " + lastRun + ". In date format : " + new Date(lastRun) + ". [-1] is no last run.");
}
nextRun.set(Calendar.HOUR_OF_DAY, 0);
nextRun.add(Calendar.HOUR_OF_DAY, hour);
nextRun.set(Calendar.MINUTE, 0);
nextRun.add(Calendar.MINUTE, minute);
nextRun.set(Calendar.SECOND,0);
nextRun.set(Calendar.MILLISECOND,0);
if(days > 0){
nextRun.add(Calendar.DAY_OF_MONTH, days);
}else if ( days ==0 && (nextRun.getTimeInMillis() - Calendar.getInstance().getTimeInMillis() < 0)) {
LOG.debug("Configured time for audit backup is elapsed and days is 0. Converting to next day run.");
nextRun.add(Calendar.DAY_OF_MONTH, 1);
}
delay = nextRun.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
if(LOG.isTraceEnabled()) {
LOG.trace("Delay computed for AuditBackup is : " + delay );
LOG.trace("Time it'll run at is : " + new Date((new Date().getTime() + delay)));
}
return delay;
}
public long getPeriod() {
long period = 0;
long daysToMillis = days * HOURS_IN_DAYS * MINS_IN_HOURS * SECS_IN_MINS * MILLIS_IN_SECS;
long hoursToMillis = hour * MINS_IN_HOURS * SECS_IN_MINS * MILLIS_IN_SECS;
long minsToMillis = minute * MINS_IN_HOURS * SECS_IN_MINS * MILLIS_IN_SECS;
period = daysToMillis + hoursToMillis + minsToMillis;
if(LOG.isTraceEnabled()){
LOG.trace("Period computed for Audit Backup thread is : " + period);
}
return period;
}
}
TimerTask实现
public class AuditBackupTimerTask extends TimerTask {
private static final Logger LOG = Logger.getLogger(AuditBackupTimerTask.class);
/**
*
* The run implementation to actually take backup.
* Actually when to run is not controlled here.
*/
@Override
public void run() {
long count = -1;
Date tillDate = null;
Date fromDate = null;
Date scheduledDate = null;
try{
my task
}
private Date getFromDate(Date tillDate) throws DbAccessException {
LOG.trace("Entering getFromDate(" + tillDate + ")...");
DateFormat dateFormat = new SimpleDateFormat(AuditUtil.DATE_FORMAT);
List<AuditEvent> events = AuditEventManager.getInstance().getAuditEventsByNamedQuery("getAuditEventsTillDateInAsc",
0, 1, null, null, dateFormat.format(tillDate), null);
LOG.debug("Returned events: " + events);
Date fromDate = null;
if(events != null && !events.isEmpty()) {
fromDate = events.get(0).getDate();
}
LOG.debug("From date: " + fromDate);
return fromDate;
}
// Take from Configuration
private Date getBackupTillDate() {
LOG.trace("Entering getBackupTillDate()...");
Calendar then = Calendar.getInstance();
then.setTime(new Date());
then.set(Calendar.HOUR_OF_DAY, 23);
then.set(Calendar.MINUTE, 59);
then.set(Calendar.SECOND, 59);
then.set(Calendar.MILLISECOND, 0);
int auditCountToKeep= (int)AuditUtil.getAuditCountToKeep();
LOG.debug("Audit counts to keep from configuration: " + auditCountToKeep);
if(auditCountToKeep > 0)
then.add(Calendar.DAY_OF_YEAR, -Math.abs(auditCountToKeep));
Date d = new Date(then.getTimeInMillis());
LOG.debug("Date till which records will be backed up : " +d);
return d;
}
}
我不确定此ScheduledExecutorTask是否未执行TimerTask,或者我的代码中是否缺少任何内容。 其次,我从Java.util.TimeTask的文档中找到了关于cancel()API的信息-
取消此计时器任务。如果已将任务计划为一次性执行并且尚未运行,或者尚未计划,则它将永远不会运行。如果计划将任务重复执行,则它将不再运行。 (如果在此调用发生时任务正在运行,则该任务将运行到完成,但将不再运行。)
stmt是什么意思- 如果已将任务安排为一次性执行,但尚未运行,或者尚未安排,则它将永远不会运行 计时器任务是否有可能无法按时执行,并且如果它没有在给定的时间执行,则永远不会执行。