Java中的定时任务应用

一. 使用Java的Timer

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,前者会等任务结束再开始计算时间间隔,后者是在任务开始就计算时间,有并发的情况

. 使用ScheduledExecutorService

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执行一次,在前一个任务开始时就开始计算时间间隔,但会等上一个任务结束再开始下一个

. 使用SpringTask

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执行一次。

. 使用Quartz框架

添加依赖

    
            org.springframework.boot
            spring-boot-starter-quartz
        

编写quartz.properties

# 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);
    }
}

你可能感兴趣的:(SpringBoot,java,spring,后端)