0
点赞
收藏
分享

微信扫一扫

解放运营人员:钡铼技术S475物联网网关实现养殖环境的远程监控与告警

c一段旅程c 2023-07-05 阅读 58

文章目录


前言

Spring Schedule是Spring框架提供的一种简单的定时任务解决方案。它是基于Java的@Scheduled注解,可以让我们在不影响主线程的情况下,定时、周期性地执行任务。

为什么选择Spring Schedule

选择Spring Schedule作为定时任务的原因主要有以下几点:

  • 简单易用:Spring Schedule的使用非常简单,只需要在方法上添加@Scheduled注解,就可以将该方法变为定时任务。
  • 集成方便:如果你的项目已经是Spring框架,那么使用Spring Schedule不需要额外引入其他依赖,只需要简单的配置即可。
  • 支持CRON表达式:Spring Schedule支持CRON表达式,这使得我们可以非常灵活地配置定时任务的执行时间。
  • 支持异步执行:Spring Schedule支持异步执行任务,这意味着定时任务的执行不会阻塞主线程。

Cron表达式

Cron 表达式是一个字符串,由多个时间字段组成,用空格分隔。一个标准的 Cron 表达式有 6 个或 7 个字段,分别表示秒、分钟、小时、日期、月份、星期以及(可选的)年份。

  • 秒(0-59)
  • 分(0-59)
  • 时(0-23)
  • 日(1-31)
  • 月(1-12 或 JAN-DEC)
  • 周(1-7 或 SUN-SAT)
  • 年(可选,留空表示任意年份)

除了上述基本的取值范围外,Cron 表达式还支持一些特殊字符,如:

*:代表所有可能的值。例如,使用 * 表示每分钟、每小时或每月等。
/:用于指定一个增量。例如,0/15 表示从 0 分钟开始,每隔 15 分钟执行一次。
-:用于指定一个范围。例如,10-20 表示从 10 到 20。
,:用于列举多个取值。例如,MON,WED,FRI 表示星期一、星期三和星期五。
?:用于天或星期字段,表示无需指定具体值。

简单示例

这里我做了一个简单的示例:这里写了两个定时任务,同一个时间往数据库里面插入数据,每个任务插入1000条数据。

@EnableScheduling
@SpringBootApplication
@MapperScan("org.example.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}

这里记得要有@EnableScheduling注解,才能使用定时任务。

package org.example.service;

import org.example.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class ScheduledService {

    @Autowired
    UserService userService;

    @Scheduled(cron = "0 08 10 * * ?")
    public void scheduledMethod(){
        System.out.println("第一个定时任务开始:"+ LocalDateTime.now());
        List<User> list = new ArrayList<User>();
        for(int i = 0;i<1000;i++){
            User user = new User();
            user.setId((long)i);
            user.setName("keaizp");
            user.setAge(25);
            list.add(user);
        }
        for (User user : list) {
            userService.insert(user);
        }
        System.out.println("第一个定时任务结束:"+ LocalDateTime.now());

    }


    @Scheduled(cron = "0 08 10 * * ?")
    public void Method2(){
        System.out.println("第二个定时任务开始:"+ LocalDateTime.now());
        List<User> list = new ArrayList<User>();
        for(int i = 1000;i<2000;i++){
            User user = new User();
            user.setId((long)i);
            user.setName("keaizp");
            user.setAge(25);
            list.add(user);
        }
        for (User user : list) {
            userService.insert(user);
        }
        System.out.println("第二个定时任务结束:"+ LocalDateTime.now());

    }
}

测试结果


可以看到定时任务会出现积压现象,虽然两个定时任务是设置同一时间的,但是第二个定时任务先执行,等第二个定时任务执行完成,第一个定时任务才开始执行。两个定时任务一共用时3分48秒。

优化方案

可以考虑使用异步执行的方式,使得任务的执行不会阻塞任务调度的进程。Spring Schedule默认是单线程执行任务的,如果有多个任务需要并行执行,那么可能会出现任务执行的延迟。这种情况下,可以考虑使用Spring Schedule的并行任务执行功能,通过配置TaskScheduler来实现。

package org.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {

    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

在这里插入图片描述
运行结果可以看到两个任务是并行执行的,两个任务完成一共用时1分54秒,效率大大得到提升!


举报

相关推荐

0 条评论