0113 spring scheduled tasks and asynchronous thread pool

Keywords: Programming Spring Java Lombok Google

0113 asynchronous method and timing task of spring

background

spring has a lot of content, and the general knowledge must be systematically learned, but some edge technology points are also very applicable in the actual work; here is an introduction and practice one by one.

Asynchronous thread pool

Scenario: the distribution task is separated from the execution task. For example, I need to do a statistics.

scene Routine practice Improved practice
Calculate daily statistics, such as daily addition, daily activity, daily retention, etc Real time computing, computing and obtaining results in the same thread There are two parts: 1. Trigger calculation; 2. Asynchronous calculation;

How to implement asynchronous computing in spring

  1. Configure asynchronous thread pool in the system;
  2. Configure @ EnableAsync annotation at the system entrance;
  3. Bid winning note in business method @Async Annotations;

Code instance:

1. Configure the thread pool and open the tag;

package com.springbootpractice.demo.spring.other.config;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Description: Custom asynchronous thread pool and exception handling
 * @author carter
 * Creation time: 10:12 am, January 13, 2020
 **/
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

    /**
     * @return Thread pool
     */
    @Override
    public Executor getAsyncExecutor() {
        return new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(10000),
                new ThreadFactoryBuilder().setDaemon(true).setNameFormat("demo_spring_other_%s").build(),
                new ThreadPoolExecutor.DiscardPolicy()
        );
    }

    /**
     * In combination with the monitoring system, it can monitor the abnormality and give an alarm
     * @return exception handling
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

2. Use code

package com.springbootpractice.demo.spring.other.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.concurrent.TimeUnit;

/**
 * Description: statistical data calculation business code
 * @author carter
 * Creation time: 10:27 am, January 13, 2020
 **/
@Service
@Slf4j
public class AsyncSummaryDataService {

    @Async
    public void calculateDayNewData(LocalDate day) {
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.info("calculateDayNewData Execution thread:{}", Thread.currentThread().getName());
    }


    @Async
    public void calculateDayLeftData(LocalDate day) {
        try {
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("calculateDayLeftData Execution thread:{}", Thread.currentThread().getName());

    }

    @Async
    public void calculateDayActiveData(LocalDate day) {
        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("calculateDayActiveData Execution thread:{}", Thread.currentThread().getName());

    }


}

  1. Test code
 @Autowired
    private AsyncSummaryDataService asyncSummaryDataService;

    @Test
    void asyncTest() {

        asyncSummaryDataService.calculateDayActiveData(LocalDate.now());
        asyncSummaryDataService.calculateDayLeftData(LocalDate.now());
        asyncSummaryDataService.calculateDayNewData(LocalDate.now());

    }

Output:


2020-01-13 10:38:02.084  INFO 35059 --- [_spring_other_1] c.s.d.s.o.s.AsyncSummaryDataService      : calculateDayLeftData Execution thread: demo_spring_other_1
2020-01-13 10:38:12.085  INFO 35059 --- [_spring_other_0] c.s.d.s.o.s.AsyncSummaryDataService      : calculateDayActiveData Execution thread: demo_spring_other_0
2020-01-13 10:38:12.092  INFO 35059 --- [_spring_other_1] c.s.d.s.o.s.AsyncSummaryDataService      : calculateDayNewData Execution thread: demo_spring_other_1
2020-01-13 10:38:12.108  INFO 35059 --- [           main] c.s.d.s.o.service.SummaryDataService     : calculateDayActiveData Execution thread: main
2020-01-13 10:38:32.114  INFO 35059 --- [           main] c.s.d.s.o.service.SummaryDataService     : calculateDayLeftData Execution thread: main
2020-01-13 10:38:42.117  INFO 35059 --- [           main] c.s.d.s.o.service.SummaryDataService     : calculateDayNewData Execution thread: main

Timing task

For B-end applications, some scheduled tasks may be required, such as month end reports. It is very simple to enable the timing task in spring. The steps are as follows:

Using steps

  1. The standard @ EnableScheduling is at the start-up entrance;
  2. Mark @ Scheduled annotation on the business method used;

@Configuration content of the Scheduled annotation** **

Configuration item Explain
cron cron expressions
zone time zone
fixedDelay,fixedDelayString Fixed delay time, execution delay between two tasks; milliseconds
fixedRate,fixedRateString Fixed frequency, fixed execution interval between two tasks < br / > milliseconds
initialDelay,initialDelayString Initialization delay: the delay of the first task after the completion of spring IOC initialization < br / > milliseconds

The cron expression can be generated directly by using tools http://cron.qqe2.com/ Recommend one; < br / > example: 0 0 0 * *? Start at 0 o'clock every day;

Instance code:

package com.springbootpractice.demo.spring.other.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.Schedules;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * Description: TODO
 * @author carter
 * Creation time: 11:14 am, January 13, 2020
 **/
@Service
@Slf4j
public class ScheduleTaskService {

    @Schedules({
            @Scheduled(initialDelay = 5 * 1000, fixedRate = 10 * 1000)
    })
    public void generateMonthReport() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("Perform monthly report calculation");
    }

}

Summary

  1. Learned to use the built-in asynchronous thread pool of spring to transform some synchronous methods into asynchronous methods;
  2. Learned to use the built-in timing tasks of spinning to complete some work;

Code point I get!

Original is not easy, reprint please indicate the source.

Posted by kryles on Sun, 12 Jan 2020 23:04:03 -0800