• SpringBoot 执行定时任务


    🧑‍🎓 个人主页:花棉袄

    📖 本章内容:【SpringBoot 执行定时任务
    ✍🏻 版权: 本文由【花棉袄】原创💝在CSDN首发💝需要转载请联系博主

    在这里插入图片描述

    🌼SpringBoot 执行定时任务🌼

    📢🌥️如果文章对你有帮助【关注👍点赞❤️收藏⭐】

    ⛲静态定时任务—基于注解

    • SpringBoot 中的 @Scheduled 注解为定时任务提供了一种很简单的实现
    • 只需要在注解中加上一些属性,例如 fixedRate、fixedDelay、cron
    • 并且在启动类上面加上 @EnableScheduling 注解,就可以启动一个定时任务了
    • 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响

    1️⃣开启定时任务

    🌳 在启动类上面加上 @EnableScheduling 注解

    @EnableScheduling
    @SpringBootApplication
    public class SpringbootTimeApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootTimeApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2️⃣创建定时任务

    /**
     * 定时任务的使用
     **/
    @Component //注入到容器
    public class Task {
    
        @Scheduled(cron = "0/5 * *  * * ? ")   //每5秒执行一次
        public void execute() {
            int count = 0;
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //设置日期格式
            System.out.println("执行第" + count++ + "次定时任务_" + df.format(new Date()));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    🥭动态定时任务—基于配置

    1️⃣开启定时任务

    🌳 在启动类上面加上 @EnableScheduling 注解

    @EnableScheduling
    @SpringBootApplication
    public class SpringbootTimeApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootTimeApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2️⃣创建配置文件

    🌳 将 cron 表达式配在 application.yml 中

    #application.yml中的配置
    scheduled:
      cron: 0/5 * * * * ?
    
    • 1
    • 2
    • 3
    @Component
    public class TestTask {
        private static SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        @Scheduled(cron = "${scheduled.cron}")
    	public void test(){
        	System.out.println(dateFmt.format(new Date()) + " : 执行定时任务");
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    🌳 如何关闭定时任务

    #application.yml中的配置
    scheduled:
      cron: "-"
    
    • 1
    • 2
    • 3

    🌳 为定时任务设置开关

    #application.yml中的配置
    scheduled:
      cron: 0/5 * * * * ?
    enable:
      scheduled: true # @Schedule 定时任务的开true/关false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 启动类上面的 @EnableScheduling 需要去掉
    • 不去除定时将一直生效,一直为true
    • 创建ScheduledCondtion类读取配置
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    
    public class ScheduledCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            //读取配置中的属性
            return Boolean.parseBoolean(context.getEnvironment().getProperty("enable.scheduled"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 创建一个 ScheduledConfig 配置类
    • 就是以 ScheduledCondtion 为条件,决定是否创建 bean
    @Configuration
    public class ScheduledConfig {
        // 根据配置文件中的内容,决定是否创建 bean
        @Conditional(ScheduledCondition.class)
        @Bean
        public ScheduledAnnotationBeanPostProcessor processor() {
            return new ScheduledAnnotationBeanPostProcessor();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    🥌多线程定时任务

    1️⃣改成异步执行

    	// 需要构建一个合理的线程池也是一个关键,否则提交的任务也会在自己构建的线程池中阻塞
        ExecutorService service = Executors.newFixedThreadPool(3);
    
        @Scheduled(cron = "0/1 * * * * ? ")
        public void task() {
            service.execute(() -> {
                log.info("执行-task()," + "异步threadId:" + Thread.currentThread().getId());
                //模拟长时间执行,比如IO操作,http请求
                try {
                    Thread.sleep(1000 * 5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    
        @Scheduled(cron = "0/1 * * * * ? ")
        public void job() {
            service.execute(() -> {
                log.info("执行-job()," + "异步threadId:" + Thread.currentThread().getId());
            });
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2️⃣配置成多线程执行

    import org.apache.commons.lang3.concurrent.BasicThreadFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.SchedulingConfigurer;
    import org.springframework.scheduling.config.ScheduledTaskRegistrar;
    
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    
    @Configuration
    @EnableScheduling
    public class MySchedulingConfigurer implements SchedulingConfigurer {
    
        /**
         * 重写配置定时任务的方法.
         */
        @Override
        public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
            scheduledTaskRegistrar.setScheduler(taskScheduler());
        }
    
        @Bean(name = "taskExecutor")
        public ScheduledExecutorService taskScheduler() {
            //创建线程池
            return new ScheduledThreadPoolExecutor(5,
                    new BasicThreadFactory.Builder().namingPattern("scheduler-pool-%d").daemon(true).build());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3️⃣使用@Async注解

    /**
     * 基于注解设定多线程定时任务.
     */
    @Component
    @EnableScheduling   // 1.开启定时任务
    @EnableAsync        // 2.开启多线程
    public class MultithreadScheduleTask{
        @Async
        @Scheduled(fixedDelay = 1000)  //间隔1秒
        public void first() throws InterruptedException {
            System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() +
                    ",线程 : " + Thread.currentThread().getName() + ",异步threadId:" + Thread.currentThread().getId());
            Thread.sleep(1000 * 10);
        }
    
        @Async
        @Scheduled(fixedDelay = 2000)
        public void second() {
            System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() +
                    ",线程 : " + Thread.currentThread().getName() + ",异步threadId:" + Thread.currentThread().getId());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    📢🌥️如果文章对你有帮助【关注👍点赞❤️收藏⭐】

  • 相关阅读:
    解决九号老C(C30/C40/C60/C80)电动车坐垫感应失灵的问题
    在线教育项目【前端路由和Ajax实现分析&与后端连接分析】
    java数据结构与算法——二叉树面试题
    MACD背离
    手写 分页
    [NPUCTF2020]ReadlezPHP 1
    基于Keras搭建CNN、TextCNN文本分类模型
    软考是什么?软考的考试安排是什么时候?
    Java设计模式-中介者模式
    java-代码操作服务器之SSH连续发送命令
  • 原文地址:https://blog.csdn.net/m0_46914264/article/details/126248798