Dans le développement réel, nous utiliserons plus ou moins certains scénarios de tâches planifiées. Cet article parlera des tâches planifiées couramment utilisées.
Les solutions de mise en œuvre de tâches planifiées couramment utilisées sont les suivantes :
Timer
: c'est l'automatique de Java Avec la classe java.util.Timer, cette classe permet de planifier un java.util.TimerTask
Tâche. L'utilisation de cette méthode permet à votre programme d'être exécuté à une certaine fréquence, mais pas à une heure spécifiée. Généralement moins utilisé. Timer
:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask
任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。ScheduledExecutorService
:也jdk自带的一个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。Spring Task
:Spring3.0
以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。Quartz
ScheduledExecutorService
: également jdk depuis Une classe fournie avec : est une classe de tâches planifiées basée sur la conception du pool de threads. Chaque tâche planifiée sera affectée à un thread du pool de threads pour son exécution. En d'autres termes, les tâches sont exécutées simultanément et ne s'affectent pas.
Spring Task
:Spring3.0
Les tâches qui viennent plus tard peuvent l'être ressemble à un quartz léger et est beaucoup plus simple à utiliser que le quartz. Quartz
: Ceci est un Un planificateur relativement puissant peut permettre à votre programme d'être exécuté à une heure précise ou à une certaine fréquence, ce qui est un peu compliqué à configurer. public class TestTimer { public static void main(String[] args) { TimerTask timerTask = new TimerTask() { @Override public void run() { System.out.println("task run:"+ new Date()); } }; Timer timer = new Timer(); //安排指定的任务在指定的时间开始进行重复的固定延迟执行。这里是每3秒执行一次 timer.schedule(timerTask,10,3000); } }
Cette méthode est similaire à Timer, il suffit de regarder la démo :
public class TestScheduledExecutorService { public static void main(String[] args) { ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); // 参数:1、任务体 2、首次执行的延时时间 // 3、任务执行间隔 4、间隔时间单位 service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS); } }
Dans le projet Spring Boot, nous pouvons l'utiliser annotation très élégante pour implémenter les tâches planifiées, créez d'abord un projet, importez les dépendances :
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
Créez une classe de tâches :
@Slf4j @Component public class ScheduledService { @Scheduled(cron = "0/5 * * * * *") public void scheduled(){ log.info("=====>>>>>使用cron {}",System.currentTimeMillis()); } @Scheduled(fixedRate = 5000) public void scheduled1() { log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis()); } @Scheduled(fixedDelay = 5000) public void scheduled2() { log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis()); } }
Utilisez l'annotation @EnableScheduling sur la classe principale pour activer la prise en charge des tâches planifiées, puis démarrez le projet
Vous pouvez voir trois Toutes les tâches planifiées ont été exécutées, et elles sont exécutées en série dans le même thread. S'il n'y a qu'une seule tâche planifiée, ce n'est certainement pas un problème lorsque le nombre de tâches planifiées augmente, si une tâche est planifiée. bloqué, les autres tâches ne pourront pas s'exécuter.
Dans les projets Spring traditionnels, nous pouvons ajouter la configuration des tâches dans le fichier de configuration XML. Dans les projets Spring Boot, nous utilisons généralement la classe de configuration config pour ajouter la configuration, créez donc un nouveau AsyncConfig
classe AsyncConfig
类
@Configuration @EnableAsync public class AsyncConfig { /* 此处成员变量应该使用@Value从配置中读取 */ private int corePoolSize = 10; private int maxPoolSize = 200; private int queueCapacity = 10; @Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.initialize(); return executor; } }
@Configuration
:表明该类是一个配置类@EnableAsync
:开启异步事件的支持
然后在定时任务的类或者方法上添加@Async
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
@Configuration
: indique que la classe est une classe de configuration@EnableAsync
: activez la prise en charge des événements asynchronesPuis dans la classe ou la méthode de la tâche planifiée Ajoutez @Async
. Enfin redémarrez le projet, chaque tâche est dans un thread différent.
initialDelay
pour. définir le délai d'exécution différé de la tâche. Une expression cron comporte au moins 6 (peut-être 7) éléments temporels séparés par des espaces. Dans l'ordre :
Chaque élément peut être une valeur (telle que 6), un intervalle continu (9-12), un intervalle (8-18/4) (/ signifie toutes les 4 heures), une liste (1, 3, 5), un caractère générique. Étant donné que les deux éléments « jour du mois » et « jour de la semaine » s'excluent mutuellement, l'un d'eux doit être défini. Exemple de configuration :
Certaines sous-expressions peuvent contenir des plages ou des listes
Par exemple : sous-expression La formule (jour (semaine)) peut être "MON-FRI", "MON, WED, FRI", "MON-WED, SAT"
Le caractère "*" représente toutes les valeurs possibles Le caractère "/" est utilisé pour préciser l'incrément de la valeur
Par exemple : "0/15" dans la sous-expression (minutes) signifie à partir de la minute 0, toutes les 15 minutes "3/20" dans la sous-expression (minutes) signifie qu'à partir de la 3ème minute, toutes les 20 minutes (il a la même signification que "3, 23, 43")
Le caractère "?" Deux sous-expressions (mois) et jour (semaine), indiquant qu'aucune valeur n'est spécifiée Lorsqu'une valeur est attribuée à l'une des deux sous-expressions, afin d'éviter les conflits, la valeur de l'autre sous-expression doit être définie sur "?"
Le caractère "L" n'est utilisé que pour le jour (mois) et le jour (semaine). ) ) deux sous-expressions, qui sont l'abréviation du mot "dernier" S’il y a quelque chose de spécifique avant le « L », cela a d’autres significations.
Par exemple : "6L" signifie le 6ème jour jusqu'à la fin de ce mois Remarque : lorsque vous utilisez le paramètre "L", ne spécifiez pas de liste ou de plage car cela entraînerait des problèmes.
Le caractère W représente les jours de la semaine (du lundi au vendredi) et ne peut être utilisé que dans le domaine du jour. Il est utilisé pour spécifier le jour de la semaine le plus proche de la date spécifiée. La plupart des traitements commerciaux sont basés sur la semaine de travail, le caractère W peut donc être très important.
Par exemple, 15W dans le champ jour signifie "le jour de la semaine le plus proche du 15 du mois". Si le 15 est un samedi, alors le déclencheur sera déclenché le 14 (vendredi), car le jeudi est plus proche du jour. Le 15 que lundi fermé.
C : signifie « Calendrier ». Cela signifie la date associée au planning, ou toutes les dates du calendrier si la date n'est pas associée.
Par exemple, 5C dans le champ date équivaut au premier jour après le 5 du calendrier. 1C dans le champ jour de la semaine correspond au premier jour après dimanche.
Champ | valeurs autorisées | caractères spéciaux autorisés |
---|---|---|
secondes | 0~59 | , - * | 0 ~59
, - * / | semaine | |
, - * ? / L C # | année (facultatif) | |
, - * / |