Several ways to implement java scheduled tasks (Timer, Spring Task, Quartz)

Timer
The Timer class of JDK allows scheduling a TimerTask task.

Demo:

/**
 * Timer Test class
 */
public class TimerDemo {
    public static void main(String[] args) {
        // Create timer
        Timer timer = new Timer();

        // Add scheduled task
        // schedule(TimerTask task, Date time);  Execute at a specific time
        // timer.schedule(new MyTask(), new Date(System.currentTimeMillis() + 1000));

        // schedule(TimerTask task, long delay); // Delay execution of task in milliseconds
        // timer.schedule(new MyTask(), 1000);

        // Schedule (TimerTask, long delay, long period) delays execution by milliseconds and executes every period milliseconds
        // timer.schedule(new MyTask(), 1000, 5000);

        // schedule(TimerTask task, Date time, long period);  Execute at a specific time and every period milliseconds
        timer.schedule(new MyTask(), new Date(System.currentTimeMillis() + 1000), 5000);

    }
}
/**
 * Specific tasks
 */
public class MyTask extends TimerTask {
    /**
     * The action to be performed by this timer task.
     */
    public void run() {
        System.out.println("execution time:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}

Spring Task:
Spring Task, a self-developed scheduled task tool after spring 3.0, supports thread pool and can efficiently handle many different scheduled tasks. In addition to spring related packages, there is no need for additional packages. It supports annotation and configuration files. But you can't handle overly complex tasks.

Configuration based Demo:

Scheduled task class:

/**
 * spring The class that performs the task
 */
public class SpringTask {
    public void show1() {
        System.out.println("show1: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

    public void show2() {
        System.out.println("show2: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">


    <bean id="springTask" class="com.zy.springtask.SpringTask"></bean>
    <!--Register scheduling task-->
    <task:scheduled-tasks>
        <!--Delay task execution by 1 second-->
        <!--<task:scheduled ref="springTask" method="show1" fixed-delay="1000" />-->

        <!--Perform the task at a fixed speed for 3 seconds-->
        <!--<task:scheduled ref="springTask" method="show2" fixed-rate="3000" />-->

        <!--
            use cron The expression specifies the trigger time
            spring task Only 6-bit cron Expression second minute hour day month week
        -->
        <task:scheduled ref="springTask" method="show1" cron="1-10 * * ? * *" />
    </task:scheduled-tasks>

    <!--Actuator configuration-->
    <task:executor id="threadPoolTaskExecutor" pool-size="10" keep-alive="5"></task:executor>

    <!--Scheduler configuration-->
    <task:scheduler id="threadPoolTaskScheduler" pool-size="10"></task:scheduler>
</beans>

Annotation based Demo:

Scheduled task class:

/**
 * spring The class that performs the task
 */
@Component
public class SpringAnnoTask {
    @Scheduled(cron = "1-10 * *  * * ? ")//Once per second in 1-10 seconds per minute
    public void show1() {
        System.out.println("show1: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

    @Scheduled(cron = "0/10 * *  * * ? ")//Every 10 seconds
    public void show2() {
        System.out.println("show2: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">

    <!--Enable annotation-->
    <task:annotation-driven></task:annotation-driven>

    <bean id="springAnnotationTask" class="com.zy.springtask.SpringAnnoTask"></bean>
</beans>

Quartz
This is great. This article can only briefly introduce an introductory case. If you need in-depth research, please check the official documents or find some series of articles on the Internet. w3cschool document

Quartz is another open source project of OpenSymphony open source organization in the field of Job scheduling. It is an open source task schedule management system completely developed by java. The "task schedule manager" is a system responsible for executing (or notifying) other software components when a predetermined (included in the schedule) time arrives.

characteristic:

Powerful scheduling function, such as supporting a variety of scheduling methods, which can meet various conventional and special needs;
Flexible application modes, such as supporting multiple combinations of tasks and scheduling, and multiple storage modes of scheduling data;
The distributed and cluster capabilities have been further improved on the basis of the original functions after Terracotta's acquisition.
In addition, as Spring's default scheduling framework, Quartz can easily integrate with Spring to realize flexible and configurable scheduling functions.
Core elements:

Scheduler: task scheduler, which is the controller that actually executes task scheduling. Encapsulated in spring through SchedulerFactoryBean.
Trigger: trigger, which is used to define the time rules of task scheduling. There are SimpleTrigger,CronTrigger,DateIntervalTrigger and NthIncludedDayTrigger. CronTrigger is used more. This paper mainly introduces this method. CronTrigger is encapsulated in CronTrigger factorybean in spring.
Calendar: it is a collection of calendar specific time points. A trigger can contain multiple calendars to exclude or include certain time points.
Job: a task is an interface with only one method void execute (JobExecutionContext). The developer implements the interface to define the running task. The JobExecutionContext class provides various information of the scheduling context. The job runtime information is saved in the JobDataMap instance. The task of implementing the job interface is stateless by default. To set the job to stateful, add the @ disallowcurrentexecution annotation to the implemented job in quartz (previously implemented StatefulJob interface, now Deprecated). In combination with spring, you can configure the concurrent parameter in the job detail of the spring configuration file.
JobDetail: task information, which is used to describe the Job implementation class and other related static information, such as Job name, associated listener and so on. There are two implementations of JobDetailFactoryBean and MethodInvokingJobDetailFactoryBean in spring. If task scheduling only needs to execute a method of a class, it can be called through MethodInvokingJobDetailFactoryBean.
Trigger:

SimpleTrigger: execute one job task within a specified time period or multiple job tasks within a specified time interval;
CronTrigger: calendar based job scheduler, rather than specifying the interval exactly as SimpleTrigger, is more commonly used than SimpleTrigger.

Simple case:
jar package dependency:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.1</version>
</dependency>
/**
 * The specific tasks implemented implement the Job interface
 */
public class MyDemoJob implements Job {
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

        // current time 
        System.out.println("execution time:" + sf.format(new Date()));

        // Get Trigger
        Trigger trigger = jobExecutionContext.getTrigger();
        // Get job ID through trigger
        JobKey jobKey = trigger.getJobKey();
        System.out.println("Job's key:" + "name:" + jobKey.getName() + "\tgroup:" + jobKey.getGroup());
        // getClass();
        System.out.println("Start time : " + sf.format(trigger.getStartTime()));
        // System.out.println("End time : " + sf.format(trigger.getEndTime()));
    }
}
/**
 *  Basic trigger scheduler
 */
public class BaseScheduler {
    public static void main(String[] args) {
        try {
            // 1. Create a JodDetail instance and bind it to the job class MyDemoJob.class to be executed
            JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class) // Define the Job class as MyDemoJob class (specific content of executing scheduled tasks)
                    .withIdentity("myJob", "default") // Define name/group
                    .build();

            // 2. Define a Trigger and execute it in 10 seconds
            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            // 2.1 set start time
            Date startTime = new Date();
            startTime.setTime(startTime.getTime() + 10000L);
            // 2.2 set end time
            // Date endTime = new Date();
            //endTime.setTime(endTime.getTime() + 20000L);

            Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "default")// Define names and groups
                    .startAt(startTime)
                    //.endAt(endTime)
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
                    // The above sentence means that this timer is executed every 5 seconds until the mountain has no edges and corners and the river no longer flows. Please check the parameter settings of withSchedule for details
                    .build();

            // 3. Create a scheduler and obtain it from the StdSchedulerFactory factory
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 4. Add jobDetail and trigger to the schedule (register task details and triggers)
            scheduler.scheduleJob(jobDetail, trigger);

            // 5. Start the scheduler
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}
/**
 * SimpleTrigger Simple trigger scheduler
 */
public class SimpleTriggerScheduler {
    public static void main(String[] args) {
        try {
            // 1. Create a JodDetail instance
            JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class)
                    .withIdentity("myJob")
                    .build();

            // 2. Define a Trigger
            Date startTime = new Date();
            startTime.setTime(startTime.getTime() + 5000L);
            SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
                    .withIdentity("myTrigger", "group1")// Define names and groups
                    .startAt(startTime)
                    .build();

            // 3. Create a scheduler
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 4. Add jobDetail and trigger to the schedule (register task details and triggers)
            scheduler.scheduleJob(jobDetail, trigger);

            // 5. Start the scheduler
            scheduler.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

CronTrigger based Demo:

/**
 * CronTrigger Trigger scheduler based on Cron expression
 */
public class CronTriggerScheduler {
    public static void main(String[] args) {
        try {
            // 1. Create a JodDetail instance
            JobDetail jobDetail = JobBuilder.newJob(MyDemoJob.class)
                    .withIdentity("myJob") // Define name/group
                    .build();

            // 2. Define a Trigger and use Cron expression to control the operation
            CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
                    .withIdentity("myTrigger", "group1")
                    .withSchedule(    //Define the time interval and times of task scheduling
                            CronScheduleBuilder
                                    .cronSchedule("0/10 * *  * * ? ")//Run every 10 seconds
                    )
                    .build();

            // 3. Create a scheduler
            SchedulerFactory sfact = new StdSchedulerFactory();
            Scheduler scheduler = sfact.getScheduler();

            // 4. Add jobDetail and trigger to the schedule (register task details and triggers)
            scheduler.scheduleJob(jobDetail, trigger);

            // 5. Start the scheduler
            scheduler.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

A simple case of integrating Quartz with Spring

PS: introduction to Cron expression

Cron expression is a string separated by 5 or 6 spaces and divided into 6 or 7 fields. Each field represents a meaning. Cron has the following two syntax formats:

​ (1)Seconds Minutes Hours DayofMonth Month DayofWeek Year

​ (2)Seconds Minutes Hours DayofMonth Month DayofWeek

Meaning of each field:

Special characters allowed for field values
Seconds is an integer from 0 to 59, - * / four characters
Minutes is an integer from 0 to 59, - * / four characters
Hours is an integer from 0 to 23, - * / four characters
The date (DayofMonth) is an integer from 1 to 31 (but you need to consider the number of days in your month), - */ L W C eight characters
The Month (Month) is an integer from 1 to 12 or JAN-DEC, - * / four characters
Day of week is an integer from 1 to 7 or SUN-SAT (1=SUN), - */ L C # eight characters
Year (optional, leave blank) (year) 1970 ~ 2099, - * / four characters

Each field uses numbers, but the following special characters can also appear, which mean:

(1) : indicates any value that matches the field. If it is used in the Minutes field, it means that an event will be triggered every minute.

(2)?: It can only be used in DayofMonth and DayofWeek domains. It also matches any value of the field, but it doesn't. Because DayofMonth and DayofWeek will affect each other. For example, if you want to trigger scheduling on the 20th of each month, no matter what day of the week the 20th is, you can only use the following expression: 13 13 15 20 *?, The last one can only use?, You can't use *. If you use *, it will trigger regardless of the day of the week. In fact, it's not the case.

(3) -: indicates the range. For example, using 5-20 in the Minutes field means that it is triggered every minute from 5 Minutes to 20 Minutes

(4) /: indicates that the trigger starts at the start time, and then is triggered every fixed time. For example, if 5 / 20 is used in the Minutes field, it means that it is triggered once every 5 Minutes, while 25, 45, etc. are triggered once respectively

(5) ,: indicates that enumeration values are listed. For example, using 5,20 in the Minutes field means that it is triggered every minute at 5 and 20 Minutes.

(6) L: indicates that it can only appear in the DayofWeek and DayofMonth domains. If 5L is used in the DayofWeek domain, it means that it is triggered on the last Thursday.

(7) W: indicates a valid working day (Monday to Friday). It can only appear in the DayofMonth field. The system will trigger the event on the nearest valid working day from the specified date. For example, 5W is used in DayofMonth. If the 5th is Saturday, it will be triggered on the latest working day: Friday, i.e. the 4th. If the 5th is Sunday, it will be triggered on the 6th (Monday); If the 5th is one of Monday to Friday, it will be triggered on the 5th. On the other hand, w's recent search will not cross the month.

(8) LW: these two characters can be used together to represent the last working day of a month, that is, the last Friday.

(9) #: used to determine the day of the week of each month. It can only appear in the DayofMonth field. For example, in 4#2, it means the second Wednesday of a month.

Tags: Java

Posted on Sat, 20 Nov 2021 02:21:19 -0500 by valentin