springboot + @Async 实现异步方法之踩坑填坑

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/oyc619491800/article/details/92759504

在这里插入图片描述

在使用@Async注解实现异步方法的时候,我们项目中实现了AsyncConfigurer接口来自定义线程池和异常处理。其中自定义线程池的代码如上图,异常处理项目中是自定义异常类实现AsyncUncaughtExceptionHandler 接口,这里未贴出代码。那么到底踩了什么坑呢?
第一:加了@Async注解的方法调不起来。由于我不是项目及代码的原创,花了很多时间才分析出问题。经过仔细分析,由于业务场景需要,我们在项目启动的时候就创建了3个线程(也就是创建了3个任务)这正好占满了核心线程数(3个),当调到@Async的方法时,相当于有新的任务进来,结合线程池的原理可知,新的任务都会放到阻塞队列里面去,直到阻塞队列满了才可能会创建新的线程来执行任务或者执行饱和策略(这与Runtime.getRuntime().availableProcessors()能获取到的线程数有关),所以造成了异步方法调不起来的假象。
解决方法:根据实际情况将线程池的核心线程数和最大线程数调整到合适的值。
第二:在解决了上一个问题后,又发现了新的问题,后面某段代码看不到执行的日志,也不知道错在哪里,没有错误日志。由于之前项目的日志并不详细,在逐步完善各处日志后,终于发现问题,报出了某个实体类没有默认构造函数的错误。在@Async异步方法中有一个把json转成实体bean的操作,由于这个bean创建了有参构造函数,却没有默认的无参构造函数,所以抛异常了,正好被getAsyncUncaughtExceptionHandler()捕捉到,由于当时此方法没有日志,也是花了点时间的。
解决方法:完善日志,给实体类加上无参构造函数。
通过这两个问题,自己也总结了一下,在使用线程池相关的知识时,一定要先了解原理,不然可能给自己挖坑,还有就是平常写代码时要养成写注释和打日志的习惯,否则出问题时可能要多花很久的时间找问题。

猜你喜欢

转载自blog.csdn.net/oyc619491800/article/details/92759504
今日推荐