转载

如何实现一个定时任务

需求说明:项目中需要每天定时更新mysql数据到另一个数据库中,暂定每天中午12:00定时启动更新任务。 实现方式:三种

第一种:使用javaJDK自带的timeTask

第一种;使用javaJDK自带的timeTask和Calendar实现定时任务,这种方式可以设置延时,执行间隔,也能设置执行时间点,我用的就是这种。
//第一种:每天中午12点定时开启任务
public static void main(String[] args) {
 //Calendar这个技术也是基于java的线程去做的
 //设置第一次更新的时间点
 Calendar calendar = Calendar.getInstance();
 calendar.set(Calendar.HOUR_OF_DAY, 12);//控制小时
 calendar.set(Calendar.MINUTE, 0);//控制分钟,
 calendar.set(Calendar.SECOND, 0);//控制秒,
 //利用java的api Timer来完成一个定时任务
 Timer timer = new Timer();
 TimerTask task=new TimerTask() {
 @Override
 public void run() {
 // 实现自己的定时任务操作
 System.out.println("这是一个定时任务!去更新数据库数据!");

 }
 };
 /*
 * 从第一次发布任务的12:00开始执行任务,每隔(1000 * 60 * 60 * 24)天,定时执行
 * */
 timer.schedule(task, calendar.getTime() , 1000 * 60 * 60 * 24);
 }
 
//第二种:定时更新,启动就开始开启定时任务,每隔2秒钟开启一次任务
 public static void main(String[] args) {
 TimerTask timerTask = new TimerTask() {
 @Override
 public void run() {
 System.out.println("定时任务启动" + new Date());
 }
 };
 Timer timer = new Timer();
//方法参数,定时执行内容,延时(单位毫秒),执行间隔(单位毫秒)
 timer.schedule(timerTask,100,2000);
 }

第二种:使用ScheduledExecutorService

第二种;使用ScheduledExecutorService执行定时任务,这个也是JDK自带的,它执行的定时任务的线程是从线程池中取,任务是并行进行的,互不影响。
 
/**
 * 使用ScheduledExecutorService执行定时任务
 */
public class get003 {
 public static void main(String[] args) {
 ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
 //参数;任务体,首次执行的延时时间,任务执行的间隔,间隔时间单位
 service.scheduleAtFixedRate(()-> System.out.println("任务启动"+new Date()),0,3, TimeUnit.SECONDS);
 }
}

第三种:结合springboot注解实现定时任务

第三种;(推荐)结合springboot注解实现定时任务,新建一个任务类,在该类上加上@Component和@EnableScheduling注解,在方法上加上@Scheduled注解,在@Scheduled注解的属性cron上加上启动时间,然后启动项目,到了任务启动时间就会去执行任务方法。可以在该类中定义多个定时任务,只需要在每个任务方法上加上@Scheduled注解即可。
 
/**
 * 定时任务,主类加上@Component和@EnableScheduling注解,在方法上加上@Scheduled注解
 * 注意的是,可以加个开关来决定任务是否执行
 */
@Slf4j
@Component
@EnableScheduling
public class TaskInfo {
//从配置文件中读取开关的值
 @Value("${task.switch.is-open}")
 private boolean flag;
 @Scheduled(cron = "${task.corn.task-corn}")
 public void m1() {
//判断开关状态
 if (flag){
 SimpleDateFormat stf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 String format = stf.format(new Date());
 System.out.println("定时任务启动->>" + format);
 }else {
 System.out.println("未开启定时任务开关,请重试!");
 }
 }
}
@Value;从配置文件中读取属性值 cron;特殊的时间格式,时分秒 年月日都是有不同的表达形式。 这里我设置了一个任务开关,当工程部署在多个服务器时,如何我想让某个时间点只有一台机器在跑定时任务,我就可以将其他的开关设置为false,需要启动的那台开关设置为true,可以灵活的控制定时任务的启动,配置文件定时任务配置如下
#定时任务
task:
 switch:
 is-open: false #开关
 corn:
 task-corn: 0 48 21 * * ? #定时任务时间格式
2021-08-16 21:47:31.255 INFO 8888 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-08-16 21:47:31.255 INFO 8888 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.38]
2021-08-16 21:47:31.555 INFO 8888 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-08-16 21:47:31.555 INFO 8888 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1174 ms
2021-08-16 21:47:31.956 INFO 8888 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-08-16 21:47:32.104 INFO 8888 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'
2021-08-16 21:47:32.151 INFO 8888 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-08-16 21:47:32.165 INFO 8888 --- [ main] com.cry.PdosWebApplication : Started PdosWebApplication in 2.181 seconds (JVM running for 3.035)
进销存web启动成功!
未开启定时任务开关,请重试!
正文到此结束
Loading...