java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Springboot @Async不执行原因

Springboot之@Async不执行原因及分析

作者:成明宁杰

这篇文章主要介绍了Springboot之@Async不执行原因及分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

背景

项目中有一个异步方法允许一段时间后就不再执行了。该异步方法是使用@Async注解的。

分析原因

1.业务场景用了@Async注解的方法,且没有使用自定义线程池。

2.ThreadPoolTaskExecutor是springboot提供的默认线程池 。

也就是说如果没有自定义线程池,那么会自动装配这个默认的。

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing.

3.ThreadPoolTaskExecutor的默认参数是由TaskExecutionProperties控制的。

默认核心线程是8,线程prefix是 “task-”。

搜索线程dump,有8个异步任务已经耗尽了线程池,且执行没有停止的迹象。

构造默认线程池方法

org.springframework.boot.task.TaskExecutorBuilder#configure 

4.如果该线程池被耗尽,则所有任务将会在线程池的队列中等待,而默认队列大小是Integer.MAX_VALUE

5.一方面要调整业务代码,使用默认线程池;另一方面也可以暂时增加默认线程池大小缓解

@Async使用总结

1、 非必须不使用异步。如果是核心业务包含事务处理,先同步记录数据,再异步发起。防止直接发起后异步没被调度到服务关闭,造成数据丢失

2、 核心业务必须使用自定义线程池,防止默认异步线程池阻塞,也方便通过线程池监控核心执行情况

3、 简单业务场景使用默认线程池时,避免操作长时间过长占用默认线程池,影响Spring以及别的框架组件异步任务执行

4、 @Async可能失效的原因    

@Async失效解决方法

如果该线程池被耗尽,则所有任务将会在线程池的队列中等待,而默认队列大小是Integer.MAX_VALUE

一方面要调整业务代码,使用默认线程池;另一方面也可以暂时增加默认线程池大小缓解

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文