1、任务执行和调度
Spring用TaskExecutor和TaskScheduler接口提供了异步执行和调度任务的抽象。
Spring的TaskExecutor和java.util.concurrent.Executor接口时一样的,这个接口只有一个方法execute(Runnable task)。
1.1、TaskExecutor类型
Spring已经内置了许多TaskExecutor的实现,你没有必要自己去实现:
1.2、注解支持调度和异步执行
To enable support for @Scheduled and @Async annotations add @EnableScheduling and @EnableAsync to one of your
@Configuration classes:
@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {
}
特别注意
The default advice mode for processing @Async annotations is "proxy" which allows for interception of calls through the proxy only; local calls within the same class cannot get intercepted that way. For a more advanced mode of interception, consider switching to "aspectj" mode in combination with compile-time or load-time weaving.
默认是用代理去处理@Async的,因此,相同类中的方法调用带@Async的方法是无法异步的,这种情况仍然是同步。
举个例子:下面这种,在外部直接调用sayHi()是可以异步执行的,而调用sayHello()时sayHi()仍然是同步执行
public class A {
public void sayHello() {
sayHi();
}
@Async
public void sayHi() {
}
}
1.3、@Async注解
在方法上加@Async注解表示这是一个异步调用。换句话说,方法的调用者会立即得到返回,并且实际的方法执行是想Spring的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.
@Async
void doSomething() {
// this will be executed asynchronously
}
@Async
void doSomething(String s) {
// this will be executed asynchronously
}
@Async
Future<String> returnSomething(int i) {
// this will be executed asynchronously
}
注意:
@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限定Executor
默认情况下,当在方法上加@Async注解时,将会使用一个支持注解驱动的Executor。然而,@Async注解的value值可以指定一个别的Executor
@Async("otherExecutor")
void doSomething(String s) {
// this will be executed asynchronously by "otherExecutor"
}
这里,otherExecutor是Spring容器中任意Executor bean的名字。
1.5、@Async异常管理
当一个@Async方法有一个Future类型的返回值时,就很容易管理在调Future的get()方法获取任务的执行结果时抛出的异常。如果返回类型是void,那么异常是不会被捕获到的。
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
// handle exception
}
}
2、线程池配置
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
@EnableAsync
public 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;
}
}
调用
@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) ? "响应异常" : 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);
}
结果
[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]
参考:
Spring Framework Reference Documentation 4.3.17.RELEASE
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持亿速云。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。