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
- Configure asynchronous thread pool in the system;
- Configure @ EnableAsync annotation at the system entrance;
- 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()); } }
- 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
- The standard @ EnableScheduling is at the start-up entrance;
- 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
- Learned to use the built-in asynchronous thread pool of spring to transform some synchronous methods into asynchronous methods;
- Learned to use the built-in timing tasks of spinning to complete some work;
Original is not easy, reprint please indicate the source.