Java中有那些定时任务的实现方式,下面从java原生和spring封装对动态管理定时任务的实现简单的聊一聊,不涉及外部组件的实现方式。
java.util包下提供了对定时任务的支持,涉及2个类:
使用该定时任务我们需要继承TimerTask抽象类,覆盖run方法编写任务执行代码,并利用Timer定时器对TimerTask进行调度。
Timer提供了多种方法,可分为一次性任务和可重复执行任务。
一次性任务是指Timer执行一次之后,该任务后续不再执行,包括2个方法:
可重复执行任务是指任务允许按照设定的规则重复执行,包括4个方法:
public class DownloadTimerTask extends TimerTask {@Overridepublic void run() {System.out.println("指定时间的任务操作内容");}
}
public static void main(String[] args) throws ParseException {// Timer执行周期任务基于绝对时间,会受到系统时间的影响Timer timer = new Timer();TimerTask downloadTimerTask = new DownloadTimerTask();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");Date date = simpleDateFormat.parse("2023-03-21 10:16:00");timer.schedule(downloadTimerTask,date);}
在idea中会看到”使用ScheduledExecutorService代替Timer吧 “提示,可见并不推荐使用Timer来实现定时任务。
java.util.concurrent包下提供了基于线程池设计的定时任务类ScheduledExecutorService,它的每个调度任务都会分配到线程池中的一个线程去执行,并发不受影响,各自执行各自的。
ScheduledExecutorService提供了3种方法:
实例:
public static void main(String[] args) {// ScheduledThreadPoolExecutor基于相对时间,不会受到系统时间的影响ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);//ScheduledExecutorService scheduledExecutorServicePool = new ScheduledThreadPoolExecutor(5, r -> new Thread(r, "executor-service-pool-" + r.hashCode()));TimerTask downloadTimerTask = new DownloadTimerTask();// 延迟5min后,运行且仅仅运行一次taskscheduledExecutorService.schedule(downloadTimerTask, 5, TimeUnit.MINUTES);}
jdk原生的两个常用线程池对象:ThreadPoolExecutor、ScheduledThreadPoolExecutor。
ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,主要用来在给定的延迟之后运行任务,或者定期执行任务。ScheduledThreadPoolExecutor的功能与Timer类似,但ScheduledThreadPoolExecutor功能更强大、更灵活。Timer对应的是单个后台线程,而 ScheduledThreadPoolExecutor可以在构造函数中指定多个对应的后台线程数。
ThreadPoolExecutor构造方法及其作用:
ScheduledThreadPoolExecutor构造方法及其作用:
实例见第2小节,ScheduledThreadPoolExecutor是接口ScheduledExecutorService的实现类。
springboot自动装配的两个常用线程池对象:ThreadPoolTaskExecutor,ThreadPoolTaskScheduler(参考org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration),分别对应jdk的两个线程池,是静态代理增强,故ThreadPoolTaskScheduler的api是最丰富的。
ThreadPoolTaskExecutor:一个专门用于执行任务的类
ThreadPoolTaskScheduler:一个专门用于调度任务的类
ThreadPoolTaskScheduler是spring中提供的线程池任务调度类,能够开启线程池进行任务调度。
ThreadPoolTaskScheduler 提供了4种定时任务方法:
ThreadPoolTaskScheduler.schedule()方法会创建一个定时计划ScheduledFuture,在这个方法需要添加两个参数,Runnable(线程接口类) 和CronTrigger(定时任务触发器),在ScheduledFuture中有一个cancel可以停止定时任务。
实例:
@Configuration
public class ThreadPoolTaskSchedulerConfig {@Beanpublic ThreadPoolTaskScheduler syncScheduler() {ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();threadPoolTaskScheduler.setPoolSize(5);threadPoolTaskScheduler.setRemoveOnCancelPolicy(true);threadPoolTaskScheduler.setThreadNamePrefix("syncThread-");return threadPoolTaskScheduler;}
}
@Slf4j
public abstract class AbstractJob implements Runnable {private ScheduledFuture> scheduledFuture;@Autowiredprivate ThreadPoolTaskScheduler threadPoolTaskScheduler;@Overridepublic void run() {begin();execute();end();}/*** 定时任务执行之前*/public void begin() {log.info("------开始执行任务------");}/*** 执行任务*/public abstract void execute();/*** 定时任务执行之后*/public void end() {log.info("------结束执行任务------");}/*** @description: 创建定时任务* @param: cron 时间表达式* @return: void*/public void createJob(String cron) {try {log.info("创建定时任务");scheduledFuture = threadPoolTaskScheduler.schedule(this, new CronTrigger(cron));} catch (Exception e) {log.error("创建定时任务失败!");e.printStackTrace();}}/*** 取消执行任务*/public void cancelJob() {try {if (scheduledFuture != null) {scheduledFuture.cancel(true);}log.info("取消执行任务!");} catch (Exception e) {log.error("取消执行失败 !");e.printStackTrace();}}}
在请求端点的方法中调用创建定时任务方法即可,结果类似如下
上一篇: 生日送花贺卡简短祝福语