本文转自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. selenium2-框架思想介绍

    为什么要有框架? 可维护性 提高编写脚本效率 提高脚本的可读性 框架的几大要素: 1. driver管理 2. 脚本 3. 数据 4. 元素对象 5. Log 6. 报告 7. 运行机制 8. 失败用 ...

  2. UVa 1309 DLX Sudoku

    16×16的数独. 看白书学的DLX,有些细节还有待消化,贴个模板先. #include <cstdio> #include <cstring> #include <al ...

  3. ie9/8的iframe中jQuery报错

    此文章用于对工作中遇到的问题进行记录 jQuery 版本:1.9.1 按照一般的思路,jquery 1.x的是支持ie9及以下的,但是今天发现jquery报错了,代码错误位置在源码版本的第4888行 ...

  4. Django Form one

    前戏: FromData:三种方式获取FromData 1. 创建一个FromData 的对象,然后再用append 的方法追个添加键值对 var formdata = new FormData(); ...

  5. 零基础学 JavaScript 全彩版 明日科技 编著

    第1篇 基础知识 第1章 JavaScript简介 1.1 JavaScript简述 1.2 WebStorm的下载与安装 1.3 JavaScript在HTML中的使用 1.3.1 在页面中直接嵌入 ...

  6. 爬虫Scrapy框架-Crawlspider链接提取器与规则解析器

    Crawlspider 一:Crawlspider简介 CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能.其中最显著 ...

  7. POJ 1315 Don't Get Rooked

    Don't Get Rooked Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2086   Accepted: 1325 ...

  8. onclick跳转到其他页面的几种方式

    如果是本页显示可以直接用location,方法如下: ①onclick="javascript:window.location.href='URL'" ②onclick=" ...

  9. 漫谈登录桩(MockStub)的实现

    2014年6月4日,6月的第一个星期三,我正式入职百度,开始baiduer的工作.这不到2个月的时间,因为人力资源这边原因,我从INF部门离开,拉到了百度Hi-Server团队中来.2个完全不着调的岗 ...

  10. HDU——1272小希的迷宫(并查集+拓扑排序)

    小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...