和timerTask的区别:
ScheduledThreadPool是在JDK1.5开始的.
Timer | ScheduledThreadPoolExecutor |
---|---|
单线程 | 多线程 |
单个任务执行时间影响其他任务调度 | 多线程,不会影响 |
基于绝对时间,对系统时间敏感 | 基于相对时间 |
一旦执行任务出现异常不会捕获,一旦出现异常,线程终止;其他任务得不到执行 | 多线程,单个任务的执行不会影响其他线程 |
1.编写ScheduledThreadPoolExecutor类,设置定时任务(每天中午12:00执行):
package com.test.amp.timerTask;
import com.test.amp.timerTask.controller.SyncUserController;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolExecutorTask {
private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
static ScheduledThreadPoolExecutor stp = null;
long initialDelayValue = 0L;
public ScheduledThreadPoolExecutorTask() {
stp = new ScheduledThreadPoolExecutor(5);
MyTask mytask = new MyTask();
try {
String thisTime = formatter.format(new Date().getTime());
String fixedTime1 = thisTime.substring(0, 10) + " 12:00";
Date date12 = formatter.parse(fixedTime1);
long MINUTE = 1000 * 60L;
//和12:00的差值
long between12 = formatter.parse(thisTime).getTime() - date12.getTime();
if (between12 >= 0) {
// 设置12点延迟时间
//如果是(0-12),设置当天的12点
initialDelayValue = (Math.abs(between12) - MINUTE) / MINUTE + 1;
} else {
//[12-24]:设置明天12点 取到24的绝对值+ 12*60*MINUTE
String fixedTime2 = thisTime.substring(0, 10) + " 24:00";
Date date24 = formatter.parse(fixedTime2);
long between24 = formatter.parse(thisTime).getTime() - date24.getTime();
initialDelayValue = (Math.abs(between24) - MINUTE) / MINUTE + 1 + 12 * 60;
}
System.out.println("initialDelayValue1----" + initialDelayValue);
} catch (Exception e) {
e.printStackTrace();
}
//scheduleWithFixedDelay,每次任务执行完之后才计算间隔时间,因为要精确的定在 12:00 与目前应用场景不符合
// stp.scheduleWithFixedDelay(mytask, 1, 2, TimeUnit.SECONDS);
//设置到12点或者15点的延迟时间, 24小时的时间间隔,任务一开始就进行计算时间间隔;单位为分钟
stp.scheduleAtFixedRate(mytask, initialDelayValue, 24 * 60, TimeUnit.MINUTES);
}
private static String getTimes() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
date.setTime(System.currentTimeMillis());
return format.format(date);
}
private static class MyTask implements Runnable {
@Override
public void run() {
System.out.println("开始执行定时任务: " + getTimes());
SyncUserController task = new SyncUserController();
task.run();
}
}
}
2.编写定时任务实现类:
package com.test.amp.timerTask.controller;
import com.test.amp.common.Common;
import com.tset.amp.exception.AjaxException;
import com.liindata.amp.timerTask.service.SyncUserService;
import com.liindata.amp.util.SpringContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@Controller
@RequestMapping("/sync/")
public class SyncUserController {
private static final Logger logger = LoggerFactory.getLogger(SyncUserController.class);
private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void run() {
SyncUserService syncUserService = (SyncUserService) SpringContextUtil.getBean("syncUserService");
try {
logger.info("定时同步用户start:" + formatter.format(Calendar.getInstance().getTime()));
syncUserService.addSyncUser();
System.out.println("======定时同步用户成功");
} catch (Exception e) {
logger.error("syncUserService.syncUser()同步用户异常:", e.getMessage());
throw new AjaxException(e);
}
}
}
3.设置监听,配置web.xml
SyncUserListener :
package com.liindata.amp.listener;
import com.liindata.amp.timerTask.ScheduledThreadPoolExecutorTask;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SyncUserListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// new TimerManager();
new ScheduledThreadPoolExecutorTask();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
web.xml:
<!--定时任务监听 start-->
<listener>
<listener-class>com.liindata.amp.listener.SyncUserListener</listener-class>
</listener>
<!--定时任务监听 end-->
SchedureThreadPoolExecutor详解参考:https://www.jianshu.com/p/925dba9f5969