目录
用ScheduledExecutorService优化定时任务类
创建一个定时任务类
@Component
public class MyScheduledTask {
private static Timer timer = new Timer();
//如果直接@Autowired为空,可尝试这种方式
private static NoticeMapper noticeMapper;
@Autowired
public void setEmployeeServer(NoticeMapper noticeMapper) {
MyScheduledTask.noticeMapper = noticeMapper;
}
//设置定时时间
//即使长时间没有操作,也可自己执行
@Scheduled(cron = "0 45 15 * * ? ")
public void n() throws ParseException {
//查询数据库中想要的数据集合 这里可以自行修改
List<String> str1 = new ArrayList<>();
List<Notice> noticeList=noticeMapper.selectList(new QueryWrapper<>());
for (Notice notice:noticeList) {
str1.add(notice.getStartTime());
}
//每次调用先关闭前面的,再重新创建
timer.cancel();
timer = new Timer();
for (String str:str1) {
String[] arr=str.split(" ");
a(arr[1]);//HH:mm:ss
}
}
//如果执行的代码需要其他的,参数可以传入实体类
public void a(String str) throws ParseException {
// 一天的毫秒数
long daySpan = 24 * 60 * 60 * 1000;
// 规定的每天时间某一时刻运行
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd "+str);
// 首次运行时间
Date startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sdf.format(new Date()));
System.out.println(sdf.format(new Date()));
// 如果今天的已经过了 首次运行时间就改为明天
// if(System.currentTimeMillis() > startTime.getTime()) {
// startTime = new Date(startTime.getTime() + daySpan);
//
// }
// 如果今天的还没到
if(System.currentTimeMillis() < startTime.getTime())
{
TimerTask task = new TimerTask(){
@Override
public void run() {
// 要执行的代码
Date date = new Date();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sendTime = dateFormat.format(date);
System.out.println("xxxxxxxxx "+sendTime);
}
};
// 以每24小时执行一次
timer.scheduleAtFixedRate(task, startTime, daySpan);
}
}
}
注意@Scheduled注解需要在启动类上加@EnableScheduling
每次创建timer会创建一个线程,如果每次都new一个timer,就会有许多一起进行的线程,所以在开头定义一个timer 然后结束旧的timer,再创建新的timer
引用这个方法
在每次增删改后任务都需要重新进行创建定时任务,其实也可不重新创建,不创建即为此日执行。
如impl层
public R updateNotice(NoticeDTO noticeDTO) throws ParseException {
Notice notice = noticeMapper.selectById(noticeDTO.getId());
notice.setStartTime(noticeDTO.getStartTime());
notice.setContent(noticeDTO.getContent());
noticeMapper.updateById(notice);
//这里引用了定时任务
MyScheduledTask.n();
return R.ok("更新成功");
}
用ScheduledExecutorService优化定时任务类
其实这里 Executors.newScheduledThreadPool() 还可以优化
@Component
public class MyScheduledTask {
private static ScheduledExecutorService pool = Executors.newScheduledThreadPool(4);
private static NoticeMapper noticeMapper;
@Autowired
public void setEmployeeServer(NoticeMapper noticeMapper) {
MyScheduledTask.noticeMapper = noticeMapper;
}
@Scheduled(cron = "0 0 0 * * ? ")
public static void n() {
//查询想要的数据集合
......
pool.shutdownNow();
pool = Executors.newScheduledThreadPool(4);
........
for (String str:str1) {
String[] arr=str.split(" ");
//HH:mm:ss
a(arr[1]);
}
}
public static void a(String str){
// 一天的毫秒数
long daySpan = 24 * 60 * 60 * 1000;
// 规定的每天时间15:33:30运行
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd "+str);
// 首次运行时间
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startTime = null;
try {
startTime = dateFormat.parse(sdf.format(new Date()));
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(sdf.format(new Date()));
// 如果今天的设定时间还没到
assert startTime != null :"时间格式不正确";
if(System.currentTimeMillis() < startTime.getTime())
{
// 以每24小时执行一次
//当前时间需要延迟多久到执行时间
long delay = startTime.getTime()-System.currentTimeMillis();
pool.scheduleAtFixedRate(() -> {
// 要执行的代码
try {
String sendTime = dateFormat.format(new Date());
System.out.println("xxxxxxxxx "+sendTime);
} catch (Exception e) {
System.out.println("定时任务出现异常");
}
}, delay, daySpan, TimeUnit.MILLISECONDS);
}
}
}
本文介绍了如何在Java中创建定时任务,强调了@Scheduled注解和@EnableScheduling的使用。讨论了避免频繁创建新线程的方法,建议在每次任务变更后更新定时任务,并探讨了ScheduledExecutorService在优化定时任务中的应用。
3286

被折叠的 条评论
为什么被折叠?



