1 introduction
There are many implementations of Scheduled tasks, such as JDK Timer, Lightweight Scheduled Tasks provided by Spring, QuartZ and Linux Cron, as well as some distributed Task scheduling frameworks. This article introduces the use of Scheduled Tasks.
2 convenient 4 ways
The @scheduled annotation can only be used on methods that satisfy one of two conditions:
(1) There is no return type, or return type void;
(2) No parameters;
Starting Spring Scheduler is as simple as @enablesCheduling:
@Configuration
@EnableScheduling
public class SchedulingConfig {
}Copy the code
For Springboot, add @enablesCheduling to the boot class.
2.1 fixedDelay fixedDelay
The interval between the beginning of the next task and the end of the previous task is always fixed, and the next task will be started only after the completion of one task. This pattern is appropriate if the requirements have such dependency requirements. The code is as follows:
@Scheduled(fixedDelay = 1000)
public void fixedDelay() {
log.info("fixedDelay");
}Copy the code
The parameter 1000 represents a fixed delay of 1000 milliseconds, i.e., 1 second, so the output is:
2019-11-19 21:02:43,977 scheduling-1:fixedDelay 2019-11-19 21:02:44,981 scheduling-1:fixedDelay 2019-11-19 21:02:45,983 The scheduling - 1: fixedDelay 21:02:46 2019-11-19, 984, the scheduling - 1: fixedDelayCopy the code
2.2 Fixed frequency fixedRate
2.2.1 Normal situation
The property of a fixed-frequency task is that the time interval between tasks is always the same. For example, if the task is executed every hour, the time interval is 1 hour. The code is as follows:
@Scheduled(fixedRate = 2000)
public void fixedRate() {
log.info("fixedRate");
}Copy the code
If the parameter is 2000, the command is executed every 2 seconds. The output is as follows:
2019-11-19 21:38:45,073 scheduling-1:fixedRate 2019-11-19 21:38:47,076 scheduling-1:fixedRate 2019-11-19 21:38:49,073 The scheduling - 1: fixedRate 21:38:51 2019-11-19, 075, the scheduling - 1: fixedRateCopy the code
2.2.2 Default Single thread
Note that it is single-threaded by default and does not execute in parallel. Even if the frequency is fixed, the next task will not start until the last one has finished. The following example is a good example:
@Scheduled(fixedRate = 1000)
public void fixedRateLongTimeTask() throws InterruptedException {
log.info("fixedRateLongTimeTask");
Thread.sleep(3000);
}Copy the code
Since the task takes 3 seconds to complete, even if fixedRate is set to 1 second, it cannot be executed every second, and the output is as follows:
2019-11-19 21:46:00,108 scheduling-1:fixedRateLongTimeTask Scheduling -1:fixedRateLongTimeTask 2019-11-19 21:46:09,117 :fixedRateLongTimeTaskCopy the code
Output every 3 times.
2.2.3 Annotation @async to help you
Is there a solution to the above problems? The answer is yes, and very simple. All you need to do is add an annotation @async to enable the task to be executed asynchronously and in multiple threads as follows:
@Async
@Scheduled(fixedRate = 1000)
public void fixedRateLongTimeTask() throws InterruptedException {
log.info("fixedRateLongTimeTask");
Thread.sleep(3000);
}Copy the code
The log shows that it is executed once per second, even if the previous task has not been completed. And the thread name is not the same, through the multi-thread execution, the output is:
The 2019-11-19 21:54:22, 261 task - 5: fixedRateLongTimeTask 21:54:23 2019-11-19, 257 task - 6: fixedRateLongTimeTask 2019-11-19 21:54:24,257 task-4:fixedRateLongTimeTask 2019-11-19 21:54:25,257 TASk-8 :fixedRateLongTimeTask 2019-11-19 21:54:26,259 Task-1 :fixedRateLongTimeTask 2019-11-19 21:54:27,262 Task-2 :fixedRateLongTimeTask 2019-11-19 21:54:28,260 task-2:fixedRateLongTimeTask 2019-11-19 21:54:28,260 task-3:fixedRateLongTimeTaskCopy the code
Note: Like @enablesCheduling, @enableAsync is added to enable this function. In addition, if the task takes a long time to execute, such as 1 minute, the situation is different. More on the use of @async later.
2.3 initialDelay
The initialDelay is specified with initialDelay, which can delay the execution of the first task. In the following example, if the parameter is 30 seconds, the system starts the first execution 30 seconds after the startup. You can ease the burden of starting a project, or you can prepare data for a task before it is executed.
@Scheduled(fixedDelay = 1000, initialDelay = 30*1000)
public void fixedDelayWithIntialDelay() {
log.info("fixedDelayWithIntialDelay");
}Copy the code
The output is as follows:
2019-11-19 22:10:092 Main :Tomcat started on port(s): 443 (HTTP) with context Path '' 2019-11-19 22:10:002,095 main:Started DemoApplication in 1.272 seconds (JVM running for 1.767) the 2019-11-19 22:10:32, scheduling - 1:063 fixedDelayWithIntialDelay 22:10:33 2019-11-19, 067 The scheduling - 1: fixedDelayWithIntialDelay 22:10:34 2019-11-19, 069 the scheduling - 1: fixedDelayWithIntialDelay 2019-11-19 22:10:35, scheduling 069-1: fixedDelayWithIntialDelayCopy the code
As you can see, about 30 seconds after the project starts, the task starts to execute.
2.4 Cron expressions
The functions provided above cannot meet all the requirements of scheduled task scheduling, such as sending SMS messages on the first day of every month and performing data analysis on every Saturday. This is where the Cron expression comes in handy.
The following example is executed whenever the number of seconds is 06. The code is as follows:
@Scheduled(cron = "6 * * ? * *")
public void cron() {
log.info("cron");
}Copy the code
The results are as follows:
2019-11-19 22:20:06,003 scheduling-1:cron
2019-11-19 22:21:06,004 scheduling-1:cron
2019-11-19 22:22:06,002 scheduling-1:cron Copy the code
Cron expressions are very powerful, there is a lot of information on the web, I won’t expand on it here.
3 Configure parameters
The previous examples left parameters in code, but if you want to be more flexible, you can actually use parameters to configure them. In this way, you can modify the configuration file without modifying the code, compiling, packaging, and deploying the parameters.
The code is as follows:
@Scheduled(cron = "${pkslow.cron}")
public void cronWithConfig() {
log.info("cronWithConfig");
}Copy the code
The configuration in application.properties is as follows:
pkslow.cron=* * * ? * *Copy the code
The code executes once every second.
4 If she suddenly disappeared
Since Spring’s Scheduler is single-threaded by default, the problem is that if a task gets stuck, it can’t proceed. It just disappears on the log. The probability of this happening is not small, such as the operation database deadlock, HTTP request timeout infinite wait, and other causes of deadlock.
When this is the case, use jstack pid > pid.threaddump.txt to get the status of the current thread, and then analyze whether it is really stuck, where it is stuck, and then analyze the specific code. To resolve the problem, set timeout or retry.
5 conclusion
This article focuses on the use of Spring’s @Scheduled annotation for Scheduled tasks, and describes various ways to use and configure them. It’s easy and concise enough to handle simple timed tasks.
Welcome to pay attention to the public number “pumpkin slow talk”, will continue to update for you…
Read more and share more; Write more. Organize more.