Grundlegender Nutzungsleitfaden für geplante Aufgaben (Cron-Zeitausdruck, Spring-eigener Scheduler, nativer JDK-Timer)

Cron-Zeitausdruck (sieben Unterausdrücke)

Ein Cron-Ausdruck, auch Zeitausdruck (sieben Unterausdrücke) genannt, ist eine durch 5 oder 6 Leerzeichen getrennte Zeichenfolge, die in 6 oder 7 Domänen unterteilt ist, von denen jeder eine andere Bedeutung darstellt

// 从左到右分别表示:秒 分 时 日 月 周 年;参数以空格隔开,其中 年 不是必须参数,可以省略。
{
    
    Seconds} {
    
    Minutes} {
    
    Hours} {
    
    DayofMonth} {
    
    Month} {
    
    DayofWeek} {
    
    Year}
Seriennummer Zeitelement Ist es erforderlich? Eingabebereich Platzhalter können ausgefüllt werden
1 Zweite Ja 0-59 , - * /
2 Punkt Ja 0-59 , - * /
3 Stunde Ja 0-23 , - * /
4 Tag Ja 1-31 , - * ? / LW
5 Mond Ja 1-12 oder JAN - DEZ , - * /
6 Woche (Montag–Sonntag) Ja 1-7 (1=SO)
oder SO, MO, DIE, MI, DO, FR, SA
, - * ? / L #
8 Jahr NEIN 1970-2099 , - * /

Gängige Platzhalter:

*	表示匹配该域的任意值,比如 Minutes 域使用 * 表示每分钟都会触发
-	表示范围,比如 Minutes 域使用 10-20 表示从10分钟到20分钟每分钟都会触发一次
,	表示列出枚举值,比如 Minutes 域使用 1,3 表示1分钟和3分钟都会触发一次
/	表示间隔时间触发(开始时间/时间间隔),例如在 Minutes 域使用 5/10 表示从第5分钟开始,每隔10分钟触发一次
?	表示不指定值,简单理解就是忽略该字段的值,直接根据另一个字段的值触发执行,仅被用于 DayofMonth 域和 DayofWeek 域中
    当这两个域其中之一被指定了值以后,为了避免冲突,需要将另一个域的值设为“?L	表示最后,是单词"last"的缩写(最后一天或最后一个星期几);仅被用于 DayofMonth 域和 DayofWeek 域中
    	用在 DayofMonth 域 表示该月的最后一天
    	用在 DayofWeek 域 表示一个星期的最后一天,也就是周六
    在使用'L'时,不要指定列表','或范围'-',否则易导致出现意料之外的结果
	如果在“L”前有具体的内容,它就具有其他的含义了
		例如:“6L”表示这个月的倒数第6天,“FRIL”表示这个月的最一个星期五
	注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题
#	表示该月第n个星期x(x#n),仅用 DayofWeek 域,如:6#3 表示该月的第三个星期五
W	仅用在 DayofMonth 域中,表示距离当月给定日期最近的工作日(周一到周五),是单词"weekday"的缩写

Hinweis: Tage und Wochen können nicht gleichzeitig Werte angeben! ! !

Beispiel:

// 每天凌晨零点执行
@Scheduled(cron ="0 0 0 * * * ?")
// 每隔五分钟执行
@Scheduled(cron ="0 */5 * * * * ?")
// 在每天下午2点到下午2:55期间的每5分钟触发
@Scheduled(cron ="0 0/5 14 * * ?")
// 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
@Scheduled(cron ="0 0/5 14,18 * * ?")
// 在每天下午2点到下午2:05期间的每1分钟触发
@Scheduled(cron ="0 0-5 14 * * ?")
// 每个星期三中午12点
@Scheduled(cron ="0 0 12 ? * WED")
// 每月的第三个星期五上午10:15触发
@Scheduled(cron ="0 15 10 ? * 6#3")
// 每年三月的星期三的下午2:10和2:44触发
@Scheduled(cron ="0 10,44 14 ? 3 WED")
// 每月最后一日的上午10:15触发
@Scheduled(cron ="0 15 10 L * ?")
// 每月的最后一个星期五上午10:15触发
@Scheduled(cron ="0 15 10 ? * 6L")

Spring kommt mit einem Planer: @Scheduled

einführen

Tatsächlich gibt es viele Plattformen von Drittanbietern, auf die für die Zeitplanung zugegriffen werden kann. Tatsächlich verfügt SpringBoot jedoch über eine eigene Annotation für Zeitaufgaben @Scheduled. @Scheduled kann die zeitliche Planung von Methoden durch die Annotationskonfiguration schnell realisieren. Fügen Sie einfach die @Scheduled-Annotation direkt zur Methode hinzu.

Bedingungen für das Öffnen zeitgesteuerter Aufgaben:

  • Die Klasse der mit @Scheduled markierten Methode wird an die Spring-Container-Verwaltung übergeben (d. h. die Spring-IOC-Annotation wird markiert).

  • Fügen Sie die Annotation @EnableScheduling zur Konfigurationsklasse oder der Klasse hinzu, in der sich die mit @Scheduled markierte Methode befindet, um die Funktion für geplante Aufgaben zu aktivieren

    Die Funktion der Annotation @EnableScheduling besteht darin, die mit @Scheduled annotierten Aufgaben zu erkennen und im Hintergrund auszuführen


@Scheduled-Annotationsparameter:

  • Cron- Parameter: Der Datentyp ist String

    Der am häufigsten verwendete Parameter bedeutet den Empfang eines Zeitausdrucks (sieben Unterausdrücke) und den Empfang von bis zu 7 Zeitelementen

  • Zonenparameter _

    Geben Sie die abzurufende Zeitzone an. Der Standardwert ist leer, d. h. die Zeitzone, in der sich der Server befindet, z. B. Asien/BeiJingi oder Asien/Shanghai

  • FixedDelay- Parameter

    Gibt die feste Zeit vom Ende der letzten Ausführung bis zur nächsten Ausführung in Millisekunden an.

    Beispiel: @Scheduled(fixedDelay= 3000) gibt an, dass es drei Sekunden nach dem letzten Aufruf ausgeführt wird

  • FixedDelayString -Parameter

    FixedDelayString ist fast dasselbe wie FixedDelay, der einzige Unterschied besteht darin, dass FixedDelayString Platzhalter unterstützt

  • FixedRate- Parameter

    Gibt an, wie oft in Millisekunden ausgeführt werden soll. Ähnlich dem / Wildcard-Effekt des Cron-Parameters

    Beispiel: @Scheduled(fixedRate= 3000) bedeutet, alle drei Sekunden auszuführen

  • FixedRateString -Parameter

    Upgrade des FixedRate-Parameters, Unterstützungsplatzhalter

  • initialDelay- Parameter

    Gibt an, um wie viele Millisekunden die Ausführung zum ersten Mal verzögert wird (in Millisekunden).

    Beispiel: @Scheduled(initialDelay= 3000) gibt an, dass die Ausführung bei der ersten Ausführung um 3 Sekunden verzögert wird

  • initialDelayString- Parameter

    Das Upgrade des initialDelay-Parameters unterstützt Platzhalter


Notiz

Wenn der Microservice mit mehreren Instanzen bereitgestellt wird, führt jede Microservice-Instanz gleichzeitig geplante Planungsaufgaben aus, was viele doppelte Daten generieren oder andere Geschäftslogikfehler im System verursachen kann. Wenn Sie @Scheduled für die Aufgabenplanung verwenden, muss es daher mit der verteilten Sperre von Redis verwendet werden, damit die geplanten Planungsaufgaben nur auf einer Microservice-Instanz ausgeführt werden, um Fehler zu vermeiden.


Anwendungsbeispiel

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
 
import java.time.LocalDateTime;
 
@Component
@Slf4j
public class Task {
    
    
    
    // 每5秒执行一次
    @Scheduled(cron = "0/5 * * * * ?")
    public void task2(){
    
    
        log.warn("现在时间:" + LocalDateTime.now());
    }
    
    // 上⼀次开始执⾏时间点之后2秒再执⾏
    @Scheduled(fixedRate = 2000)
    public void task(){
    
    
        log.warn("现在时间:" + LocalDateTime.now());
    }
}

Nativer JDK-Timer

einführen

Mit dem Timer können Sie den Thread so einstellen, dass er zu einem bestimmten Zeitpunkt etwas ausführt oder zu einem bestimmten Zeitpunkt startet und in bestimmten Intervallen wiederholt etwas ausführt

java.util.Timer- Klasse : ist eine Klasse, die einen Timer beschreibt

Eine Funktion, die ein Thread verwendet, um Aufgaben für die spätere Ausführung in einem Hintergrundthread zu planen. Aufgaben können so geplant werden, dass sie einmal ausgeführt werden oder sich in regelmäßigen Abständen wiederholen.

Konstruktionsmethode:

public Timer()		// 创建一个新计时器。

Mitgliedsmethode:

// 终止此计时器,丢弃所有当前已安排的任务
void cancel()
    // 注意,在此计时器调用的计时器任务的 run 方法内调用此方法,就可以绝对确保正在执行的任务是此计时器所执行的最后一个任务。
    
// 在指定的毫秒值之后,执行指定的任务,只会执行一次
void schedule(TimerTask task, long delay) 	
// 在指定的毫秒值之后,执行指定的任务,之后每隔固定的毫秒数重复执行定时任务
void schedule(TimerTask task, long delay, long period)
// 安排在指定的时间执行指定的任务,只会执行一次
void schedule(TimerTask task, Date time) 
// 安排指定的任务在指定的时间开始进行重复的固定延迟执行
void schedule(TimerTask task, Date firstTime, long period) 
/* 参数:
		task		所要安排的任务。定时器到时间之后要执行的任务
		delay		执行任务前的延迟时间,单位是毫秒。 多个毫秒之后开始执行TimerTask任务
		period		执行各后续任务之间的时间间隔,单位是毫秒。定时器开始执行之后,每隔多少毫秒重复执行
		time		执行任务的时间。从什么日期开始执行任务  20020-07-06 15:25:13
		period		执行各后续任务之间的时间间隔,单位是毫秒。定时器开始执行之后,每隔多少毫秒重复执行
*/

TimerTask-Klasse : eine einmalige oder wiederkehrende Aufgabe, die von einem Timer ausgeführt wird

java.util.TimerTask implementiert die Runnable- Schnittstelle

Die TimerTask-Klasse ist eine abstrakte Klasse und kann nicht direkt erstellt werden

Member-Abstract-Methode:

// 此计时器任务要执行的操作。重写run方法,设置线程任务
void run()

Anwendungsbeispiel

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Demo01Timer {
    
    
    public static void main(String[] args) throws ParseException {
    
    
        show04();
    }
    
    /*
        在指定的毫秒值之后,执行指定的任务,只会执行一次
        void schedule(TimerTask task, long delay) 
    */
    private static void show01() {
    
    
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("c4爆炸了!");
                timer.cancel();
            }
        }, 5000);
    }
    
    /*
        在指定的毫秒值之后,执行指定的任务,之后每隔固定的毫秒数重复执行定时任务
        void schedule(TimerTask task, long delay, long period)
     */
    private static void show02() {
    
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Timer timer =new Timer();
        timer.schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println(sdf.format(new Date()));
            }
        }, 5000, 1000);
    }
    
    /*
        安排在指定的时间执行指定的任务,只会执行一次
        void schedule(TimerTask task, Date time) 
     */
    private static void show03() throws ParseException {
    
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse("2020-07-06 15:32:50");
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("哈哈!");
                timer.cancel();
            }
        }, date);
    }

    /*
        安排指定的任务在指定的时间开始进行重复的固定延迟执行
        void schedule(TimerTask task, Date firstTime, long period) 
     */
    private static void show04() throws ParseException {
    
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse("2020-07-06 15:37:30");
        Timer timer  = new Timer();
        timer.schedule(new TimerTask() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("嘿嘿,你中招了!");
            }
        }, date, 10);
    }
}

Guess you like

Origin blog.csdn.net/footless_bird/article/details/126679351