本文转自http://blog.csdn.net/clementad/article/details/47403185 感谢作者

这个注解用于标注某个方法或某个类里面的所有方法都是需要异步处理的。被注解的方法被调用的时候,会在新线程中执行,而调用它的方法会在原来的线程中执行。这样可以避免阻塞、以及保证任务的实时性。适用于处理log、发送邮件、短信……等。

注解的应用范围:
  • 类:表示这个类中的所有方法都是异步的
  • 方法:表示这个方法是异步的,如果类也注解了,则以这个方法的注解为准
 
相关的配置:
<task:annotation-driven />配置:
  • executor:指定一个缺省的executor给@Async使用。
例子:
<task:annotation-driven executor="asyncExecutor" />
 
<task:executor />配置参数:
  • id:当配置多个executor时,被@Async("id")指定使用;也被作为线程名的前缀。
  • pool-size
    • core size:最小的线程数,缺省:1
    • max size:最大的线程数,缺省:Integer.MAX_VALUE
  • queue-capacity:当最小的线程数已经被占用满后,新的任务会被放进queue里面,当这个queue的capacity也被占满之后,pool里面会创建新线程处理这个任务,直到总线程数达到了max size,这时系统会拒绝这个任务并抛出TaskRejectedException异常(缺省配置的情况下,可以通过rejection-policy来决定如何处理这种情况)。缺省值为:Integer.MAX_VALUE
  • keep-alive:超过core size的那些线程,任务完成后,再经过这个时长(秒)会被结束掉
  • rejection-policy:当pool已经达到max size的时候,如何处理新任务
    • ABORT(缺省):抛出TaskRejectedException异常,然后不执行
    • DISCARD:不执行,也不抛出异常
    • DISCARD_OLDEST:丢弃queue中最旧的那个任务
    • CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
 
配置例子:
 <task:annotation-driven executor="asyncExecutor" />
 <task:executor id="asyncExecutor" pool-size="100-10000" queue-capacity="10"/>
 
实例:
  1. <!-- 缺省的异步任务线程池 -->
  2. <task:annotation-driven executor="asyncExecutor" />
  3. <task:executor id="asyncExecutor" pool-size="100-10000" queue-capacity="10" />
  4. <!-- 处理log的线程池 -->
  5. <task:executor id="logExecutor" pool-size="15-1000" queue-capacity="5" keep-alive="5"/>
  1. @Override
  2. @Async("logExecutor")    //如果不指定名字,会使用缺省的“asyncExecutor”
  3. public void saveUserOpLog(TabUserOpLog tabUserOpLog) {
  4. userOpLogDAO.insertTabUserOpLog(tabUserOpLog);
  5. }

(注意:如果在同一个类中调用的话,不会生效,原因请参考:http://blog.csdn.net/clementad/article/details/47339519

 
通过log可以看到,已经分开两个线程执行:
 
线程的优先级和类型:
优先级:NORM_PRIORITY
类型:非守护线程
 
用户线程(User Thread):JVM会等待所有的用户线程结束后才退出;当系统中没有用户线程了,JVM也就退出了
守护线程(Daemon Thread):一般是为其他线程提供服务的线程,比如GC垃圾回收器;JVM退出时,不会管守护线程是否存在,而是直接退出
所以,对于文件、数据库的操作,不适宜使用守护线程,不然可能会丢失数据!
 
Web应用停止时,Spring容器会被关闭,调用者如果是Spring bean,就会停止生成新任务。然而,线程池中已经在运行的任务,由于缺省是用户线程,所以JVM会等待它们结束后才退出。
 
附:Java编程方式的配置方法:
  1. @Configuration
  2. @EnableAsync
  3. public class SpringConfig {
  4. /** Set the ThreadPoolExecutor's core pool size. */
  5. private int corePoolSize = 10;
  6. /** Set the ThreadPoolExecutor's maximum pool size. */
  7. private int maxPoolSize = 200;
  8. /** Set the capacity for the ThreadPoolExecutor's BlockingQueue. */
  9. private int queueCapacity = 10;
  10. private String ThreadNamePrefix = "MyLogExecutor-";
  11. @Bean
  12. public Executor logExecutor() {
  13. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  14. executor.setCorePoolSize(corePoolSize);
  15. executor.setMaxPoolSize(maxPoolSize);
  16. executor.setQueueCapacity(queueCapacity);
  17. executor.setThreadNamePrefix(ThreadNamePrefix);
  18. // rejection-policy:当pool已经达到max size的时候,如何处理新任务
  19. // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
  20. executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  21. executor.initialize();
  22. return executor;
  23. }
  24. }

Spring异步任务处理,@Async的配置和使用的更多相关文章

  1. 关于Dubbo和Spring异步注解@Async的冲突

    项目中难免会有异步处理的需求,像异步记录日志啦,异步发送邮件啦,而Dubbo又是现在主流的分布式框架,所有异步+Dubbo的组合是再所难免的 但博主是实践中发现Dubbo的服务并不能很好的跟Sprin ...

  2. Spring异步执行(@Async)2点注意事项

    Spring中可以异步执行代码,注解方式是使用@Async注解. 原理.怎么使用,就不说了. 写2点自己遇到过的问题. 1.方法是公有的 // 通知归属人 @Async public void not ...

  3. 工作随笔——spring异步处理@Async使用笔记

    @Async使用笔记 必须是public方法 必须是非static方法 方法调用的实例必须由spring创建和管理 代码示例如下: // 创建Foo类@Component class Foo { @A ...

  4. Spring异步-@Async注解

    Spring异步:@Async注解 使用@Async前需要开启异步支持:@EnableAsync 注解和XML方式 @Async返回值的调用:需要使用Future包装 1.如果没有使用Future包装 ...

  5. Spring及SpringBoot @Async配置步骤及注意事项

    前言 最近在做一个用户反馈的功能,就是当用户反馈意见或建议后服务端将意见保存然后发邮件给相关模块的开发者.考虑发邮件耗时的情况所以我想用异步的方法去执行,于是就开始研究Spring的@Async了.但 ...

  6. spring中使用@Async注解进行异步处理

    引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在spring 3. ...

  7. Spring中异步注解@Async的使用、原理及使用时可能导致的问题

    前言 其实最近都在研究事务相关的内容,之所以写这么一篇文章是因为前面写了一篇关于循环依赖的文章: <面试必杀技,讲一讲Spring中的循环依赖> 然后,很多同学碰到了下面这个问题,添加了S ...

  8. SpringBoot异步使用@Async原理及线程池配置

    前言 在实际项目开发中很多业务场景需要使用异步去完成,比如消息通知,日志记录,等非常常用的都可以通过异步去执行,提高效率,那么在Spring框架中应该如何去使用异步呢 使用步骤 完成异步操作一般有两种 ...

  9. spring boot / cloud (四) 自定义线程池以及异步处理@Async

    spring boot / cloud (四) 自定义线程池以及异步处理@Async 前言 什么是线程池? 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线 ...

随机推荐

  1. linux学习-用户的特殊 shell 与 PAM 模块

    特殊的 shell, /sbin/nologin 『无法登入』指的是:『这个使用者无法使用 bash 或其他 shell 来登入系统』而已, 并不是说这个账号就无法使用其他的系统资源! 让某个具有 / ...

  2. luogu4001 [BJOI2006]狼抓兔子

    裸dinic就跑过去了,哪用得着平面图最小割=最短路-- #include <iostream> #include <cstring> #include <cstdio& ...

  3. luogu2761 软件补丁问题

    状压最短路 #include <iostream> #include <cstring> #include <cstdio> #include <queue& ...

  4. 前端AI切图技巧

    AI的基本使用 1.选中多个不同图层. 首先在AI右边工具栏找到“图层” 然后选择需要切图的图层(按住“ctrl”点击) 最后拖到PS里面的新建的图层. 还有个问题,就是图层关联太多,无法拖动某些图层 ...

  5. ccna 闫辉单臂路由 和 acl access control list

    ccna 闫辉单臂路由 和  acl   access control list 一单臂路由     当前园区网设计很少用到       成本低  小型的.局域网可用         二ACL acc ...

  6. TOJ4505: KOSARE

    TOJ4505: KOSARE  Time Limit(Common/Java):10000MS/30000MS     Memory Limit:65536KByteTotal Submit: 11 ...

  7. HAZU校赛 Problem K: Deadline

    Problem K: Deadline Time Limit: 2 Sec Memory Limit: 1280 MB Submit: 1106 Solved: 117 [Submit][Status ...

  8. javascript学习笔记 - 执行环境及作用域

    一 执行环境(环境) 1.每个执行环境都有一个关联的全局变量对象.例如:web浏览器中,window对象为全局变量对象.环境中定义的所有变量和函数都保存在该对象中.全局执行环境是最外围的环境. 2.执 ...

  9. java EE技术体系——CLF平台API开发注意事项(3)——API安全访问控制

    前言:提离职了,嗯,这么多年了,真到了提离职的时候,心情真的很复杂.好吧,离职阶段需要把一些项目中的情况说明白讲清楚,这篇博客就简单说一下在平台中对API所做的安全处理(后面讲网关还要说,这里主要讲代 ...

  10. 九度oj 题目1496:数列区间

    题目描述: 有一段长度为n(1<=n<=1000000)的数列,数列中的数字从左至右从1到n编号.初始时数列中的数字都是0. 接下来我们会对其进行m(1<=m<=100000) ...