@Async异步注解与SpringBoot结合使用
2021-06-29 05:04
标签:输出 enable 返回值 嵌套 cto object lin 调用 nested 当你在service层需要启动异步线程去执行某些分支任务,又不希望显式使用Thread等线程相关类,只想专注于实现业务逻辑代码开发,可以使用@Async异步注解。 1、 使用@Async 异步注解 Controller层方法: Service层方法,是真正使用@Async异步注解的: 2、@Async异步注解使用注意点 a)该注解可使用在类、接口(包括注释类型)或枚举声明 b)当被标注在方法级别时,该方法返回值要么是void,或java.util.concurrent.Future接口实现类 3、自定义异步注解真正的执行线程类(可选) 4、日志监控异步线程活动(可选) logback.xml配置文件中设置 %thread 纪录线程执行名 @Async异步注解与SpringBoot结合使用 标签:输出 enable 返回值 嵌套 cto object lin 调用 nested 原文地址:https://www.cnblogs.com/zhuwenjoyce/p/9647189.html//批量插入用户
@RequestMapping("/user/addSystemUser")
public void batchAddUser(@RequestParam(value = "usernameList[]",required=false) List usernameList){
for (int i = 0; i ) {
//使用异步线程执行每一个用户新增
userService.addUser(usernameList.get(i));
}
}
@Transactional(propagation = Propagation.NESTED) //如果当前事务存在,则在嵌套事务中执行。如果没有,就新建一个事务;
@Async
public void addUser(SystemUser sessionUser, List
如果懒得自己写一个线程执行类的话,我猜SpringBoot会默认设置一些org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor类的配置。
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 创建自定义配置的线程池
*/
@Configuration
@EnableAsync
public class MyTaskExecutePool implements AsyncConfigurer {
private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(ASyncTask.class);
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(20);
//最大线程数
executor.setMaxPoolSize(40);
//队列容量
executor.setQueueCapacity(50);
//活跃时间
executor.setKeepAliveSeconds(30);
//线程名字前缀
executor.setThreadNamePrefix("MyTaskExecutePool-");
// setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
/**
* 异步任务中异常处理
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncUncaughtExceptionHandler() {
@Override
public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) {
//纪录log错误日志
LOG.error("exception method:"+arg1.getName()+";"+arg0.getMessage(), arg0);
}
};
}
}
appender name="console" class="ch.qos.logback.core.ConsoleAppender">
filter class="ch.qos.logback.classic.filter.ThresholdFilter">
level>DEBUGlevel>
filter>
encoder>
pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %msg - %file:%line%npattern>
charset>UTF-8charset>
encoder>
appender>