1. Task execution and scheduling
Spring uses the TaskExecutor and TaskScheduler interfaces to provide abstractions for asynchronous execution and scheduling tasks.
Spring's TaskExecutor is the same as the java.util.concurrent.Executor interface. This interface has only one method execute(Runnable task).
1.1. TaskExecutor type
Spring has built-in many TaskExecutor implementations, and you don't need to implement them yourself:
1.2. Annotations support scheduling and asynchronous execution
To enable support for @Scheduled and @Async annotations add @EnableScheduling and @EnableAsync to one of your
@Configuration classes:@Configuration@EnableAsync@EnableSchedulingpublic class AppConfig {}Pay special attention
The default advice mode for processing @Async annotations is "proxy" which allows for interference of calls through the proxy only; local calls within the same class cannot get intercepted that way. For a more advanced mode of interference, consider switching to "aspectj" mode in combination with compile-time or load-time welding.
By default, @Async is handled with proxy. Therefore, methods in the same class cannot be asynchronously called methods with @Async, and this situation is still synchronous.
For example: The following, calling saysHi() directly externally can be executed asynchronously, while sayingHi() is still executed synchronously when calling saysHello()
public class A { public void saysHello() { sayHi(); } @Async public void saysHi() { } }1.3. @Async annotation
Adding @Async annotation to the method means that this is an asynchronous call. In other words, the caller of the method will get the return immediately, and the actual method execution is to submit a task in Spring's TaskExecutor.
In other words, the caller will return immediately upon invocation and the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor.
@Asyncvoid doSomething() { // this will be executed asynchronously} @Asyncvoid doSomething(String s) { // this will be executed asynchronously} @AsyncFuture<String> returnSomething(int i) { // this will be executed asynchronously}Notice:
@Async methods may not only declare a regular java.util.concurrent.Future return type but also Spring's org.springframework.util.concurrent.ListenableFuture or, as of Spring 4.2, JDK 8's java.util.concurrent.CompletableFuture: for richer interaction with the asynchronous task and for immediate composition with further processing steps.
1.4. @Async limited Executor
By default, when @Async annotation is added to the method, an Executor that supports annotation driver will be used. However, the value value of the @Async annotation can specify an additional Executor
@Async("otherExecutor")void doSomething(String s) { // this will be executed asynchronously by "otherExecutor"}Here, otherExecutor is the name of any Executor bean in the Spring container.
1.5. @Async exception management
When a @Async method has a return value of Future type, it is easy to manage the exception thrown when typing Future's get() method to get the execution result of the task. If the return type is void, then the exception will not be caught.
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler { @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { // handle exception }} 2. Thread pool configuration
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configuration@EnableAsyncpublic class TaskExecutorConfig { private Integer corePoolSize = 30; private Integer maxPoolSize = 50; private Integer keepAliveSeconds = 300;// private Integer queueCapacity = 2000; @Bean("myThreadPoolTaskExecutor") public ThreadPoolTaskExecutor myThreadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setKeepAliveSeconds(keepAliveSeconds);// executor.setQueueCapacity(queueCapacity); executor.setWaitForTasksToCompleteOnShutdown(true); executor.initialize(); return executor; }} Call
@Async("myThreadPoolTaskExecutor") @Override public void present(CouponPresentLogEntity entity) { try { CouponBaseResponse rst = couponSendRpcService.send(entity.getUserId(), entity.getCouponBatchKey(), "1", entity.getVendorId()); if (null != rst && rst.isSuccess()) { entity.setStatus(PresentStatusEnum.SUCCESS.getType()); }else { String reason = (null == rst) ? "Response Exception" : rst.getMsg(); entity.setFailureReason(reason); entity.setStatus(PresentStatusEnum.FAILURE.getType()); } }catch (Exception ex) { log.error(ex.getMessage(), ex); entity.setFailureReason(ex.getMessage()); entity.setStatus(PresentStatusEnum.FAILURE.getType()); } couponPresentLogDao.update(entity); }result
[INFO ] 2018-05-09 16:27:39.887 [myThreadPoolTaskExecutor-1] [com.ourhours.coupon.rpc.dubbo.ReceiveLogFilter] - receive method-name:send; arguments:[10046031,"4d7cc32f8f7e4b00bca56f6bf4b3b658","1",10001]
[INFO ] 2018-05-09 16:27:39.889 [myThreadPoolTaskExecutor-2] [com.ourhours.coupon.rpc.dubbo.ReceiveLogFilter] - receive method-name:send; arguments:[10046031,"4d7cc32f8f7e4b00bca56f6bf4b3b658","1",10001]
refer to:
Spring Framework Reference Documentation 4.3.17.RELEASE
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.