import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TimerUtil {
public static void playOne() {
new Timer("Timer1").schedule(new TimerTask() {
@Override
public void run() {
System.out.println("TimerTask1");
}
}, 1000, 2000);
}
public static void playTwo() throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse("2023-08-10 10:14:00");
new Timer("Timer2").scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("TimerTask2");
}
},date,2000);
}
}
date是开始时间,2000ms是定时任务周期,每2s执行一次
timer有2种方法:schedule和scheduleAtFixedRate,前者会等任务结束再开始计算时间间隔,后者是在任务开始就计算时间,有并发的情况
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduleUtil {
public static void playThree(){
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("ScheduledTask1");
}
},1,1, TimeUnit.SECONDS);
}
}
延迟1s启动,每隔1s执行一次,在前一个任务开始时就开始计算时间间隔,但会等上一个任务结束再开始下一个
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class SpringTask {
private static final Logger log = LoggerFactory.getLogger(SpringTask.class);
@Scheduled(cron = "1/5 * * * * *")
public void task1() {
log.info("SpringTask1 定时任务1");
}
@Scheduled(initialDelay = 1, fixedRate = 1 * 1000)
public void task2(){
log.info("SpringTask2 定时任务2");
}
}
task1是每隔5s执行一次,{秒} {分} {时} {日期} {月} {星期};
task2是延迟1s,每隔1S执行一次。
org.springframework.boot
spring-boot-starter-quartz
# ThreadPool 实现的类名
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 线程数量
org.quartz.threadPool.threadCount=10
# 线程优先级
org.quartz.threadPool.threadPriority=5
# 自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread= true
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.io.IOException;
import java.util.Properties;
@Configuration
@EnableScheduling
public class SchedulerConfig {
@Bean(name = "SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setQuartzProperties(quartzProperties());
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
//在quartz.properties中的属性被读取并注入后再初始化对象
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/**
* quartz初始化监听器
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/**
* 通过SchedulerFactoryBean获取Scheduler的实例
*/
@Bean(name = "Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
}
import org.quartz.*;
import java.time.LocalDateTime;
/**
* 例子:定义一个执行输出语句的任务
*/
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello执行:" + LocalDateTime.now());
}
}
import com.example.ratelimit.demos.util.HelloJob;
import org.junit.jupiter.api.Test;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;
@SpringBootTest
class RateLimitApplicationTests {
@Test
void contextLoads() {
}
@Test
public void quartzTest() throws SchedulerException {
// 1. 创建工厂类 SchedulerFactory
SchedulerFactory factory = new StdSchedulerFactory();
// 2. 通过 getScheduler() 方法获得 Scheduler 实例
Scheduler scheduler = factory.getScheduler();
scheduler.clear();
// 3. 使用上文定义的 HelloJob
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
//job 的name和group
.withIdentity("jobName2", "jobGroup2")
.build();
//3秒后启动任务
Date statTime = new Date(System.currentTimeMillis() + 3000);
// 4. 启动 Scheduler
scheduler.start();
// 5. 创建Trigger
//使用SimpleScheduleBuilder或者CronScheduleBuilder
SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
.withIdentity("trigger", "group")
.startAt(new Date())
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(3)
.withRepeatCount(0))//重复执行的次数,因为加入任务的时候马上执行了,所以不需要重复,否则会多一次。
.build();
// 6. 注册任务和定时器
scheduler.scheduleJob(jobDetail, simpleTrigger);
}
}