SpringBoot uses timed tasks to reveal all 6 of ways

  • 2021-06-29 10:50:47
  • OfStack

The purpose of this paper is to tell the dull knowledge in common language

As a system scheduling tool, timed tasks are widely used in some systems that need timed jobs, such as statistical data at a certain point in time, executing certain actions at a certain time in the future. Timed tasks provide corresponding API for developers in the mainstream development language. There are many ways to implement timed tasks in Java.To achieve a complete timer task in a native way requires two classes, Timer and TimerTask. Timer is a timer class used to open background threads on schedule to perform specified tasks. TimerTask is an abstract class whose subclasses represent a task that can be scheduled by Timer.In addition, you can use the ScheduledExecutorService class or the third-party jar library Quartz, in which Quartz is an excellent timed task framework, which has matured so far that the core ideas or underlying layers of other timed task frameworks were mostly derived from Quartz.

springboot is a framework for the development of Java. Timing tasks in the springboot project can be implemented not only in the native way provided by Java, but also in the timed task API provided by springboot. Below, this site integrates all the ways Java and springboot implement timed tasks.

Outline of Article:
1. Use threads
2. Use the Timer class
3. Use the ScheduledExecutorService class
4. Use Quartz
5. Use the @Scheduled comment from spring
6. cron expression

1. Thread implementation

Simple timed task logic can be implemented by using threads to set hibernation times.


  public static void main(String[] args){
    // Timed Task Interval 
    int sleepTime=2*1000;
    new Thread(new Runnable() {
      @Override
      public void run() {
        while (true){
          try {
            System.out.println("Thread Method Execution 1 Secondary timed task ");
            // Thread Sleep Schedule Time 
            Thread.sleep(sleepTime);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    }).start();
  }

2. Timer class

The Timer class allows dispatching an TimerTask task.This way you can have your program execute at a certain frequency.


  public static void main(String[] args){
    int sleepTime=2*1000;
    TimerTask timerTask = new TimerTask() {
      @Override
      public void run() {
        System.out.println("Timer Method Execution 1 Secondary timed task ");
      }
    };
    new Timer().schedule(timerTask,1,sleepTime);
  }

3. ScheduledExecutorService class

ScheduledExecutorService is a timed task class designed based on a thread pool. Each dispatch task is assigned to one thread in the thread pool to execute, that is, tasks are executed concurrently without interacting with each other.

Therefore, the timed task class based on the ScheduledExecutorService class is ultimately thread-based scheduling.


  public static void main(String[] args){
    int sleepTime=2*1000;
    ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
    scheduledExecutor.scheduleAtFixedRate(
        new Runnable() {
          @Override
          public void run() {
            System.out.println("ScheduledExecutorService Method Execution 1 Secondary timed task ");
          }
        }
    ,1,sleepTime, TimeUnit.SECONDS);
  }

4. Integrate Quartz

Quartz is an open source job scheduling framework written entirely by Java. It provides a simple but powerful mechanism for job scheduling in Java applications. To understand how it is used, several core concepts need to be understood first:

Job: Represents a job, the specific content to be performed.There is only one method in this interface, as follows:
void execute(JobExecutionContext context)

JobDetail: Represents a specific executable dispatcher, Job is what this executable dispatcher is about to execute, and JobDetail also contains the schema and strategy for this task scheduling. Trigger: Represents the configuration of a dispatch parameter and when to dispatch it. Scheduler: Represents a dispatch container in which multiple JobDetails and Triggers can be registered.When Trigger is combined with JobDetail, it can be dispatched by the Scheduler container.

With these concepts, we can integrate Quartz into our springboot project.

Introducing quartz dependencies


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

To configure


@Configuration
public class QuartzConfig {
  @Bean
  public JobDetail quartzDetail(){
    return JobBuilder.newJob(QuartzTest.class).withIdentity("QuartzTest").storeDurably().build();
  }
  @Bean
  public SimpleTrigger quartzTrigger(){
    SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
        .withIntervalInSeconds(10)
        .repeatForever();
    return TriggerBuilder.newTrigger().forJob(quartzDetail())
        .withIdentity("QuartzTest")
        .withSchedule(scheduleBuilder)
        .build();
  }
}

test


public class QuartzTest extends QuartzJobBean {
  @Override
  protected void executeInternal(JobExecutionContext jobExecutionContext){
    System.out.println("quartz implement 1 Secondary timed task  ");
  }
}

5. Use the Scheduled annotation

@Scheduled is an spring comment for a timed task. See the source of the comment:


@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
//cron Expression 
  String cron() default "";
// Receive 1 individual java.util.TimeZone#ID . 
  String zone() default "";
// upper 1 How long to execute after the point in time for the second execution 
  long fixedDelay() default -1;
// Supports string types in placeholder form fixedDelay
  String fixedDelayString() default "";
// upper 1 How long to execute after the start point of the second execution 
  long fixedRate() default -1;
// Supports string types in placeholder form fixedRateString
  String fixedRateString() default "";
// No. 1 How long is the delay before execution   
  long initialDelay() default -1;
// Supports string types in placeholder form initialDelay
  String initialDelayString() default "";
}

It can be seen that the parameters in the Scheduled annotation are used to set the "timer" action. Usually, the more common parameter is cron(), which means we need to learn some cron expression-related grammar, but because of the large content and the long length of the text, we will leave the cron grammar related at the end of the article.Here's how to use the Scheduled annotation to accomplish a timed task.

Turn on Timed Task Support


@SpringBootApplication
/**
 *  Turn on Timed Task Support 
 */
@EnableScheduling
public class TestApplication extends SpringBootServletInitializer {
  public static void main(String[] args) {
    SpringApplication.run(TestApplication.class, args);
  }
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(this.getClass());
  }
}

Use


@Component
public class ScheduledTest {
  private Logger logger = LoggerFactory.getLogger(ScheduledTest.class);
  /**
   *  each 15 Seconds execution 1 Secondary timed task 
   */
  @Scheduled(cron = "0/15 * * * * ? ")
  public void testCron(){
    logger.info("Scheduled  implement 1 Secondary timed task ");
  }
}

6. cron expression

The cron expression is a string whose syntax is:

[seconds] [minutes] [hours] [days] [months] [weeks] [years]

The [year] is not required, so usually the cron expression consists of 6 or 7 parts of the content, the value of which is either a number or a special character specified in the cron expression, which is called a "wildcard", each wildcard refers to a value.The cron expression can be expressed in a table like this:

顺序 取值范围 特殊字符串范围
0~60 , - * /
0-60 , - * /
0-23 , - * /
1-31 , - * /
1-12 / JAN-DEC , - * ? / L W
1-7 / SUN-SAT , - * ? / L #
年(可省略) 1970-2099 , - * /

Wildcards are interpreted and used as follows:

通配符 代表的值 解释
* 所有值 如:时字段为*,代表每小时都触发
? 不指定值 如:周字段为?,代表表达式不关心是周几
- 区间 如:时字段设置2-5,代表2,3,4,5点钟时都触发
, 多个值 如:时字段设置2,3,5,代表2,3,5点都会触发
/ 递增值 如:时字段设置0/2,代表每两个小时触发,时字段设置 2/5,代表从2时开始每隔5小时触发1次
L 最后值 如:日字段设置L,代表本月最后1天
W 最近工作日 如:在日字段设置13W,代表没约13日最近的那个工作日触发1次
# 序号 如:在周字段设置5#2,代表每月的第2个周5

Example:
Execute every 2 seconds: 0/5 ?
Execute every 5 minutes: 0/5 * ?
1, 12, 45 points executed once: 0 1, 12, 45 * ?
Execute once a day at 23:59 minutes and 59 seconds: 59,5923 ?
Execute once a month on 15th at 3am: 0.0315 * ?
Execute once a month at 12 o'clock on the last day of the month: 0 0 12 L * ?


Related articles: