Java scheduled task

I haven't really encountered the scenario of using timed tasks yet. Anyway, learn it first

1. Scheduled tasks

In many cases, tasks do not need to be executed immediately, but need to be executed later or regularly, which cannot be operated manually, so timed tasks appear. The use of scheduled tasks will certainly be used in the project. The author needs to pull the buried point data regularly

Use of scheduled tasks:

  • Backup data every weekend
  • Email notification will be sent 5 minutes after triggering the condition
  • Order cancellation without payment in 30 minutes
  • Pull data every hour
  • ......

2. Thread implementation

The method of rushing to come up with a fixed task for the first time in the written examination

2.1 use

public class ThreadSchedule {
    public static void main(String[] args) {
      
        // Execute the task in 5 seconds
        int interval = 1000 * 5;

        // New thread execution
        new Thread(() -> {
            try {
                Thread.sleep(interval);
                System.out.println("Perform scheduled tasks");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

2.2 analysis

  • The timing is not accurate. Due to the dependence on the underlying hardware, the Windows error is 10%
  • System.currentTimeMillis() depends on system hardware and is also modified by network time synchronization
  • System.nanoTime() depends on the running nanoseconds of the JVM and is not affected by synchronization. It is suitable for calculating the accurate time difference
  • However, the Greenwich mean time of currentTimeMillis is still used to calculate the current date, while nanoTime is inaccurate to calculate the JVM running time

3. java.util.Timer

Timer is responsible for executing the planning function and will start a background thread, while TimerTask is responsible for task logic

3.1 use

public class TimeSchedule {
    public static void main(String[] args) {
        
        // Start a daemon thread
        Timer timer = new Timer();  
        
        // Timed task
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Perform scheduled tasks");
            }
        };

        long delay = 0;     		// Delayed execution
        long period = 1000 * 5;  	// interval
        timer.scheduleAtFixedRate(timerTask, 1, period);
        // timer.cancel(); 			    Cancelable
    }
}

3.2 analysis

// The final constructor of new Timer() will start a thread
public Timer(String name) {
    thread.setName(name);
    thread.start();
}

// This thread encapsulates a Queue priority Queue. This thread will go to the Queue and keep executing the tasks in it
class TimerThread extends Thread {
    private TaskQueue queue;
    TimerThread(TaskQueue queue) {
        this.queue = queue;
    }
}

// This queue stores various TimerTask timed task logic
class TaskQueue {
    private TimerTask[] queue = new TimerTask[128];
}
  • There is only one single thread execution, so it is serial execution
  • A long execution time of a task will block the tasks scheduled to be executed later, so the time is not accurate
  • When the thread reports an error, the subsequent scheduled task stops directly

4. ScheduledExecutorService

The tool class in java.util.concurrent is a multithreaded timer

4.1 use

public class ExecutorSchedule {
    public static void main(String[] args) {
        
        // Timed task
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Perform scheduled tasks");
            }
        };

        // Thread pool execution
        long delay = 0;     		// Delayed execution
        long period = 1000 * 5;  	// interval
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(runnable, delay, period, TimeUnit.MILLISECONDS);
}

The author's most commonly used timing operation, and has written timing detection tasks before

5. Spring's scheduled tasks

The timing function @ enableshcheduling needs to be enabled

@Component
public class SpringSchedule {
    
    // cron expression, executed once per second
    
    @Scheduled(cron = "*/1 * * * * ?")
    public void springSchedule(){
        System.out.println("Perform scheduled tasks");
    }
    
}

The bottom layer is the ScheduledThreadPoolExecutor thread pool, which has the same root and source as the ScheduledExecutorService above

6. XXL-JOB

XXL job is a personal maintenance distributed task scheduling framework (written by Chinese people with detailed Chinese documents), which is divided into scheduling center and actuator. The executor is a scheduled task, and the scheduling center is responsible for managing and calling these scheduled tasks. The scheduling center can also store scheduled tasks and distribute them to each service in real time in the form of script (Java is Grovvy) without compilation. The most important thing is to have a UI interface and a user-friendly experience

6.1 establishment of database

The storage of XXL job is based on the database. Compared with quartz, it can be saved in memory and database, which has a little performance impact. The first step is to build a database. There is an SQL statement tables on the XXL job official website_ xxl_ Job.sql, which can be directly executed to create databases and tables

6.2 deploy XXL job admin dispatching center

Pull the latest code from Git, compile the root module, fill in the database address of admin module, and then start the dispatching center (Docker deployment is supported, which is more convenient)

6.3 creating scheduled tasks

Introduce dependencies, add configurations, and create scheduled tasks in services that require scheduled tasks

6.3.1 dependence

<!-- xxl-job-core -->
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>${project.parent.version}</version>
</dependency>

6.3.2 basic configuration

# xxl-job admin address
xxl.job.admin.addresses=http://xxx.xxx.xxx:8080/xxl-job-admin

# xxl-job executor appname
xxl.job.executor.appname=xxl-job-executor-demo

6.3.3 scheduled tasks

@Component
public class MyJob {
    
    @XxlJob("MyJob")
    public void MyJob() throws Exception {
        
        // Actuator logging
        XxlJobHelper.log("myjob is execute");
        
        // Timed task logic
        System.out.println("myjob is executing");
        
        // default success
    }
}

6.4 perform scheduled tasks

Enter the dispatching center, create a new task, and then execute the scheduled task (using RPC remote procedure call)

6.5 problems encountered

The default actuator is automatically registered in the dispatching center, but there are often problems with the address that leads to execution failure, so you should manually enter the address of the actuator

6.6 analysis

As a lightweight distributed scheduled task, it has a UI interface, which is simple and convenient to use, and has no invasion to the code. It can meet the needs of most projects. If I want to use scheduled tasks, I will also choose XXL job

Posted by tidalik on Tue, 23 Nov 2021 18:45:29 -0800