方案一:Timer
(1)Timer.schedule(TimerTask task,Date time)安排在制定的时间执行指定的任务。
(2)Timer.schedule(TimerTask task,Date firstTime ,long period)安排指定的任务在指定的时间开始进行重复的固定延迟执行.
(3)Timer.schedule(TimerTask task,long delay)安排在指定延迟后执行指定的任务.
(4)Timer.schedule(TimerTask task,long delay,long period)安排指定的任务从指定的延迟后开始进行重复的固定延迟执行.
(5)Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)安排指定的任务在指定的时间开始进行重复的固定速率执行.
(6)Timer.scheduleAtFixedRate(TimerTask task,long delay,long period)安排指定的任务在指定的延迟后开始进行重复的固定速率执行.
public class TestTimer{
public static void main(String[] args){
TimerTask timerTask = new TimerTask(){
@Override
public void run(){
System.out.println("tesk run:" + new Date());
}
};
Timer timer = new Timer();
//安排指定的任务在指定的时间开始进行重复的而固定延迟执行,每3庙执行一次
timer.schedule(timeTask,10,3000);
}
}
方案二:ScheduleExecutorService
public class TestScheduleExecutorService{
public static void main(String[] args){
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
/**
参数:任务体、首次执行的延时时间、任务执行间隔、间隔时间单位
*/
service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()),
0, 3, TimeUnit.SECONDS);
}
}
方案三:SpringTask
Cron表达式:若干数字、空格、符号按照一定的规则组成一组字符串来表达时间信息。在线corn表达式生成器:https://www.pppet.net/
标准格式:A B C D E F G
A表示秒;B表示分;C表示小时;D表示日;E表示月;F表示星期;G表示年
spring3.0以后自带的task
注解方式:
<!--启动定时任务的注解驱动-->
<task:annotation-driven/>
@Slf4j
@Component
public class ScheduledService{
@Scheduled(cron = "0/5 * * * * *")
public void scheduled(){
log.info("====>使用cron {}",System.currentTimeMillis());
}
@Scheduled(fixedRate = 5000) //每5秒运行一次
public void scheduled1(){
log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
}
@Scheduled(fixedDelay = 5000)
public void scheduled2() {
log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
}
}
配置方式:
<!--配置定时任务-->
<task:scheduled-tasks>
<!--<task:scheduled ref="job1" method="run" cron="0/5 * * * * ?"/>-->
<task:scheduled ref="job1" method="run" fixed-rate="5000"/>
</task:scheduled-tasks>
每5秒执行一次
public class job1 {
public void run(){
System.out.println("job1....."+new Date());
}
}
方案四:多线程执行
基于注解设置多线程
@Component
@EnableScheduling //开启定时任务
@EnableAsync //开启多线程
public class MultithreadScheduleTask{
@Async
@Scheduled(fixedDDelay = 5000) //间隔5秒
public void first(){
System.out.println("第一个定时任务开始:" + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
System.out.println();
Thread.sleep(1000 * 10);
}
@Async
@Scheduled(fixedDelay = 5000)
public void second() {
System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
System.out.println();
}
}
方案五:quartz
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
@Configuration
public class QuartzConfig{
@Bean
public JobDetail teatQuaritzDetail(){
return JobBuilder.newJob(MyAuartz.class).withIdentity("myQuartz").storeDurably().build();
}
@Bean
public Trigger testQuartzTrigger(){
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(10) //设置时间周期单位
.repeatForever();
return TriggerBuilder.newTrigger().forJob(testQuartzDetail())
.withIdentity("testQuartz")
.withSchedule(scheduleBuilder)
.build();
}
}
只要启动SpringBoot羡慕就会输出:
配置的方式:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.2</version>
</dependency>
<!-- 线程池 -->
<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="10" />
<property name="maxPoolSize" value="100" />
<property name="queueCapacity" value="500" />
</bean>
<!--FixedRate 定时任务 -->
<bean id="quartzJob" class="com.wanmait.mavendemo.job.QuartzJob" />
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="quartzJob" />
<property name="targetMethod" value="print" />
</bean>
<!-- Cron quartz-2.x 的配置 时间调度的两种写法 fixedRate和cron-->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean" >
<property name="jobDetail" ref="jobDetail" />
<property name="cronExpression" value="0/5 * * * * ?" />
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail"></property>
<property name="startDelay" value="0" />
<!-- 调度工厂实例化后,经过 0 秒 开始执行调度 -->
<property name="repeatInterval" value="2000" />
<!-- 每 2 秒调度一次 -->
</bean>
<!-- 调度 看你用哪个 两种选一种 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!--<ref bean="simpleTrigger" />-->
<ref bean="cronTrigger"/>
</list>
</property>
<property name="taskExecutor" ref="executor" />
</bean>
public class QuartzJob{
public void print(){
System.out.println("quartzjob.........."+new Date());
}
}
SpringBoot定时任务:
在启动类上加@EnableScheduling开启定时任务
写一个任务类添加@Component注解被spring管理,在方法上添加@Scheduled(fixedRate = 2000)或者 @Scheduled(cron = “0-5 * * ? * *”)
动态调整定时任务执行corn表达式、动态关闭开启定时任务
@Configuration
public class ScheduledConfig implements SchedulingConfigurer{
@Autowired
private ApplicationContext context;
@Override
public void confugureTasks(ScheduledTaskRegistrar taskRegistrar){
for(SpringScheuledCron springScheduledCron:cronRepository.findAll()){
Class<?> clazz;
Object task;
try{
clazz = Class.forName(springScheduledCron.getCronKey());
task = context.getBean(clazz);
}catch(ClassNotFoundException e){
throw new IllegalArgumentException("spring_scheduled_cron表数据" + springScheduledCron.getCronKey() + "有误", e);
}catch(BeansException e){
throw new IllegalArgumentException(springScheduledCron.getCronKey() + "未纳入到spring管理", e);
}
Assert.isAssignable(ScheduledOfTask.class, task.getClass(), "定时任务类必须实现ScheduledOfTask接口");
//可以通过改变书库数据进而实现动态改变执行周期
taskRegistrar.addTriggerTask(((Runnable)task),
triggerContext -> {
//可以使用持久层,比如Mybatis来实现,从数据库中获取
String cronExpression = "0/10 * * * * ?";
return new CronTrigger(cronExpression).nextExecutionTime(triggerContext);
}
);
}
}
@Bean
public Executor taskExecutor(){
return Executors.newScheduledThreadPool(10);
}
}
分布式调度框架
分布式任务调度框架有:cronsun、Elastic-job、saturn、lts、TBSchedule、xxl-job 等。