@Async失效之谜
@Async如何使用
- 异步的方法上加上@Async异步注解
- 启动类中需要加上@EnableAsync才有效
使用时类似于下列函数:
new Thread(()-> System.out.println("hello world !"))
@Async线程池
- 默认线程池
无论重复多少次,都默认8个左右的线程在跑
异步线程:task-1执行成功
异步线程:task-2执行成功
异步线程:task-3执行成功
异步线程:task-4执行成功
异步线程:task-5执行成功
异步线程:task-6执行成功
异步线程:task-7执行成功
异步线程:task-1执行成功
异步线程:task-2执行成功
异步线程:task-8执行成功
异步线程:task-3执行成功
异步线程:task-8执行成功
异步线程:task-6执行成功
异步线程:task-8执行成功
异步线程:task-5执行成功
异步线程:task-3执行成功
异步线程:task-2执行成功
异步线程:task-1执行成功 - 自定义线程池配置
/**
* 为Async配置自定义线程池
* 可存放的最多线程数为:MAX_POOL_SIZE+QUEUE_CAPACITY,同时进入线程池的数量超过这个就会报错
* 线程名称最多为MAX_POOL_SIZE个
*/
@Configuration
public class MyTaskExecutorConfig implements AsyncConfigurer {
/**
* 设置ThreadPoolExecutor的核心池大小。
*/
private static final int CORE_POOL_SIZE = 2;
/**
* 设置ThreadPoolExecutor的最大池大小。
*/
private static final int MAX_POOL_SIZE = 3;
/**
* 设置ThreadPoolExecutor的BlockingQueue的容量。
*/
private static final int QUEUE_CAPACITY = 5;
/**
* 配置类实现AsyncConfigurer接口并重写getAsyncExcutor方法,并返回一个ThreadPoolTaskExevutor
* 这样我们就获得了一个基于线程池的TaskExecutor
*/
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
taskExecutor.setQueueCapacity(QUEUE_CAPACITY);
taskExecutor.initialize();
return taskExecutor;
}
}
异步线程:ThreadPoolTaskExecutor-2执行成功
异步线程:ThreadPoolTaskExecutor-1执行成功
异步线程:ThreadPoolTaskExecutor-3执行成功
异步线程:ThreadPoolTaskExecutor-1执行成功
异步线程:ThreadPoolTaskExecutor-3执行成功
异步线程:ThreadPoolTaskExecutor-2执行成功
异步线程:ThreadPoolTaskExecutor-1执行成功
异步线程:ThreadPoolTaskExecutor-3执行成功
@Async和@Controller同时使用存在异常
AbstractHandlerMethodMapping初始bean时,在afterPropertiesSet方法中initHandlerMethods()关联我们的SpringMVCBean
// 类型判断
if (beanType != null && isHandler(beanType)) {
// url处理
detectHandlerMethods(beanName);
}
// Controller和RequestMapping注解判断
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
a、@Controller不使用@Async注解时
@RestController
@Slf4j
public class MemberServiceImpl1 {
@GetMapping("/addUser1")
public String addUser() {
log.info(">>>流程1");
log.info(">>>流程2");
return "success";
}
}

b、@Controller使用@Async注解,但不继承接口时,异步失效
@RestController
@Slf4j
public class MemberServiceImpl3 {
@GetMapping("/addUser3")
public String addUser() {
log.info(">>>流程1");
addUserLog();
log.info(">>>流程3");
return "success";
}
@Async()
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}


c、@Controller使用@Async注解,同时继承接口
@RestController
@Slf4j
public class MemberServiceImpl4 implements MemberService {
@Override
@GetMapping("/addUser4")
public String addUser() {
log.info(">>>流程1");
addUserLog();
log.info(">>>流程3");
return "success";
}
@Async()
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}


@Async使用建议
- a、异步执行的建议单独开启一个类实现,或者从容器中直接获取到该代理类后执行
/**
* 异步代码写到别的地方,不要和Controller注解同时使用
*/
@RestController
@Slf4j
public class ResolveServiceImpl {
@Autowired
private MemberServiceManage memberServiceManage;
@GetMapping("/resolve2")
public String addUser() {
log.info(">>>流程1");
memberServiceManage.addUserLog();
log.info(">>>流程3");
return "success";
}
}
@Component
@Slf4j
public class MemberServiceManage {
@Async
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}
/**
* 使用SpringUtils获得bean后调用,不要使用this操作
*/
@RestController
@Slf4j
public class ResolveServiceImpl {
@GetMapping("/resolve1")
public String addUser() {
log.info(">>>流程1");
//把直接调用改为从容器中取一次
ResolveServiceImpl bean = SpringUtils.getBean(ResolveServiceImpl.class);
bean.addUserLog();
log.info(">>>流程3");
return "success";
}
@Async()
public String addUserLog() {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
log.info(">>>流程2");
return "success";
}
}
- b、异步的方法上不要加static,加了static就不走AOP了
@Async失效之谜的更多相关文章
- springboot2.0 如何异步操作,@Async失效,无法进入异步
springboot异步操作可以使用@EnableAsync和@Async两个注解,本质就是多线程和动态代理. 一.配置一个线程池 @Configuration @EnableAsync//开启异步 ...
- Spring AOP失效之谜
每天学习一点点 编程PDF电子书免费下载: http://www.shitanlife.com/code 什么是AOP1 AOP(Aspect Oriented Programming),即面向切面编 ...
- Spring aop注解失效
问题 在spring 中使用 @Transactional . @Cacheable 或 自定义 AOP 注解时,对象内部方法中调用该对象的其他使用aop机制的方法会失效. @Transactiona ...
- SpringBoot线程池的创建、@Async配置步骤及注意事项
最近在做订单模块,用户购买服务类产品之后,需要进行预约,预约成功之后分别给商家和用户发送提醒短信.考虑发短信耗时的情况所以我想用异步的方法去执行,于是就在网上看见了Spring的@Async了. 但是 ...
- 关于AOP无法切入同类调用方法的问题
一.前言 Spring AOP在使用过程中需要注意一些问题,也就是平时我们说的陷阱,这些陷阱的出现是由于Spring AOP的实现方式造成的.每一样技术都或多或少有它的局限性,很难称得上完美,只要掌握 ...
- Java开发技术
1.基础技术 数据结构与算法 逻辑结构:数据对象中的数据元素之间的逻辑关系 1.集合结构:集合结构中的数据元素除了同属一个集合外,没有其他关系. 2.线性结构:线性结构中的数据元素之间是一对一的关 ...
- 如何在Spring异步调用中传递上下文
以下文章来源于aoho求索 ,作者aoho 1. 什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步 ...
- 关于Spring注解@Async引发其他注解失效
概述 在前面一篇文章中,介绍,在一个Bean中注入自己,如果有@Async和@Transaction,如果使用@Autowire注入自身,会报循环依赖,如果使用BeanFactoryAware注入自己 ...
- 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法
参考原贴地址:https://blog.csdn.net/clementad/article/details/47339519 在同一个类中,一个方法调用另外一个有注解(比如@Async,@Trans ...
随机推荐
- 【Spring Cloud + Vue 有来商城】研发小组开发规范全方位梳理
项目演示 后端 Spring Cloud实战 | 第一篇:Windows搭建Nacos服务 Spring Cloud实战 | 第二篇:Spring Cloud整合Nacos实现注册中心 Spring ...
- NB-IoT的低功耗是怎么实现的?
NB-IoT的低功耗是怎么实现的? NB-IoT可以实现低功耗的一个主要原因就是NB-IoT设备的用户终端在省电模式下依然可以工作,这种工作模式可以极大的降低电量的消耗和延长电池使用寿命.在省电模式下 ...
- Cobalt Strike使用的一些技巧
利用msf模块上线beacon shell 当通过CS的mimikatz或者其他方式获得了目标机器的明文密码或者哈希时,可以利用metasploit的psexec_command模块来上线CS的bea ...
- [LuoguP3808] 【模板】AC自动机(简单版)数组版
待填坑 Code #include<iostream> #include<cstdio> #include<queue> #include<cstring&g ...
- Python + Appium 自动化操作微信入门看这一篇就够了
简介 Appium 是一个开源的自动化测试工具,支持 Android.iOS 平台上的原生应用,支持 Java.Python.PHP 等多种语言. Appium 封装了 Selenium,能够为用户提 ...
- 修改redo log 的大小
alert日志中含有大量警告信息:"Thread 1 cannot allocate new log, sequence 320xx Checkpoint not complete" ...
- C语言实现天气信息管理系统
这篇文章主要介绍了C语言实现天气信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了C语言实现天气信息管理系统的具体代码,供大家参考,具体内 ...
- 【java】校验当前时间是否在规定的时间内
废话不多说直接贴代码. 我的日期格式是 8:00-22:00 要用的自己换下格式哈. public class CheckClosingTimeUtil { /** * 校验当前时间是否在规定时间内 ...
- 斯福赛特:中了.Devos勒索病毒。所有文件被加密了,如何解密解决?
什么是.devos勒索病毒? 也称为DHARMA勒索软件1,它通过加密文件并要求支付赎金以恢复对文件的访问来修改您的文件. DHARMA勒索软件通过名为.devos的新加密病毒再次活跃.该特定的病毒家 ...
- linux kernel 的 procfs sysfs 对查问题的帮助
遇到进程卡死,没有gdb 符号表:只能strace 跟踪处理分析 排查过程: 1.ps -aux 查看卡死进程pid 2.strace -T -tt -e trace=all -p 查看卡死进程系统调 ...