spring中异步方法的配置

1、把方法放在一个单独的service类中,用@Async标注方法,用@EnableAsync标注类。也可以用@Async标注service类。

这个时候,这个方法就是异步方法了,调用时会异步执行。但是,每执行一次这个方法都要生成一个线程(线程名以"SimpleAsyncTaskExecutor-"开头),执行完之后线程再销毁。这样很不好,最好有一个线程池,每次方法执行的时候都从线程池中取线程,执行完之后再放回到线程池中。这就有了第2步。

2、在applicationContext.xml中配置一个ExecutorService实例。方法有很多种,以下只是其中一种:

    <bean id="asyncThreadPoolExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="20"/>
<property name="maxPoolSize" value="40"/>
<property name="keepAliveSeconds" value="0"/>
<property name="queueCapacity" value="3000"/>
<property name="threadNamePrefix" value="asyncThreadPool-"/>
</bean>

如果不用上述方法显式地创建线程池,则也可以在applicationContext.xml文件中配置

 <task:executor id="annotationExecutor" pool-size="20-40" queue-capacity="3000" keep-alive="0" rejection-policy="ABORT"/>

这样就会产生一个ThreadPoolTaskExecutor实例。不过这种方式生成的线程池里的线程的名字不能像第一种方法那样自定义,而是固定以"annotationExecutor-"为开头的。

如果配置了多个<task:executor/>,则需要在配置@Async注解的时候,配置其value属性值为某个executorId,这样执行方法时就会使用这个指定的线程池,如@Async(value = "xxx"),否则不会用任何一个线程池,而是每执行一次就创建一个线程。

以上配置针对没有返回值的方法没问题,但是如果异步方法有返回值,而且想要获取该方法的返回值,那么这个异步方法就不能简简单单的返回原来想返回的值类型了,得返回xxxFuture<T>类型。阿里规约插件提醒如下:@Async methods should return void, java.util.concurrent.Future, org.springframework.util.concurrent.ListenableFuture or java.util.concurrent.CompletableFuture。

示例如下:

    @Async(value = "annotationExecutor")
public ListenableFuture<String> print() {
try {
Thread.sleep(3000);
LOGGER.info("async thread: " + Thread.currentThread().getName());
} catch (Exception e) {
LOGGER.error(e);
}
return new AsyncResult<String>("异步返回值");
}

AsyncResult全类名是org.springframework.scheduling.annotation.AsyncResult,实现了ListenableFuture接口。

需要特别提醒下, <task:annotation-driven/>这个跟异步没有半毛钱关系。跟定时任务有点关系,配置了的话,就不用@EnableScheduling注解了。

spring中定时任务的配置

1、用@Scheduled标注方法,用@EnableScheduling标注类,就可以了。

这时现在每执行一次定时任务,就会创建一个线程,执行完后销毁。需要引入线程池。这就需要第2步

2、在applicationContext.xml中配置如下:

    <bean id="scheduledThreadPoolExecutor" class="java.util.concurrent.ScheduledThreadPoolExecutor">
<constructor-arg name="corePoolSize" value="10"/>
<constructor-arg name="threadFactory" ref="threadFactory"/>
</bean>

并新建一个Config类(类名随便),内容如下:

@Configuration
public class Config {
@Bean("threadFactory")
public ThreadFactory getThreadFactory() {
return new ThreadFactoryBuilder().setNameFormat("scheduled-pool-%d").setPriority(10).setDaemon(false).build();
}
}

如果不用上述方法显式创建定时任务线程池,则还可以在applicationContext.xml中配置:

<task:scheduler id="scheduler" pool-size="5"/>

这种方法会生成一个指定大小的org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler实例。不过同样不能自定义线程名,线程名固定以"scheduler-"开头。

实际测试发现,如果既显式配置ScheduledExecutorService实例,又配置<task:scheduler/>的话,定时任务会用<task:scheduler/>对应的线程池。显示配置的ScheduledExecutorService实例没用。

最佳实践:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.google.common.util.concurrent.ThreadFactoryBuilder; @Configuration
public class Config { @Bean("asyncThreadPoolExecutor")
public ExecutorService getThreadPoolExecutor() {
return new ThreadPoolExecutor(20,
40,
0,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3000),
new ThreadFactoryBuilder().setNameFormat("asyncThreadPool-%d").setPriority(10).setDaemon(false).build(),
new ThreadPoolExecutor.AbortPolicy());
} @Bean("scheduledThreadPoolExecutor")
public ScheduledExecutorService getThreadFactory() {
return new ScheduledThreadPoolExecutor(10,
new ThreadFactoryBuilder().setNameFormat("scheduledThreadPool-%d").setPriority(10).setDaemon(false).build(),
new ThreadPoolExecutor.AbortPolicy());
} }

spring对异步的支持的更多相关文章

  1. Java RMI 介绍和例子以及Spring对RMI支持的实际应用实例

    RMI 相关知识 RMI全称是Remote Method Invocation-远程方法调用,Java RMI在JDK1.1中实现的,其威力就体现在它强大的开发分布式网络应用的能力上,是纯Java的网 ...

  2. Spring对jdbc支持

    4. Spring对jdbc支持 spring对jdbc提供了很好的支持 体现在: 1.Spring对C3P0连接池的支持很完善 2.Spring对jdbc提供了jdbcTemplate来简化jdbc ...

  3. 【杂谈】Spring Boot 默认支持的并发量

    Spring Boot应用支持的最大并发量是多少? Spring Boot 能支持的最大并发量主要看其对Tomcat的设置,可以在配置文件中对其进行更改.当在配置文件中敲出max后提示值就是它的默认值 ...

  4. Spring Batch JSON 支持

    Spring Batch 4.1 开始能够支持 JSON 格式了.这个发布介绍了一个新的数据读(item reader)能够读取一个 JSON 资源,这个资源按照下面的格式: [   {     &q ...

  5. 8 -- 深入使用Spring -- 4...4 Spring 的 AOP 支持

    8.4.4 Spring 的AOP 支持 Spring中的AOP代理由Spring的IoC容器负责生成.管理,器依赖关系也由IoC容器负责管理.因此,AOP代理可以直接使用容器中的其他Bean实例作为 ...

  6. Spring框架事务支持模型的优势

    全局事务 全局事务支持对多个事务性资源的操作,通常是关系型数据库和消息队列.应用服务器通过JTA管理全局性事务,API非常烦琐.UserTransaction通常需要从JNDI获取,意味着需要与JND ...

  7. spring对事务支持的三种形式

    spring对事务支持的三种形式: 1.通过spring配置文件进行切面配置 <bean id="***Manager" class="org.springfram ...

  8. Spring Boot 版本支持对应JDK

    转自:http://www.cnblogs.com/oumi/p/9241424.html 一.Spring Boot 版本支持 Spring Boot Spring Framework Java M ...

  9. spring注解不支持静态变量注入

    spring注解不支持静态变量注入:今天敲代码  自动配置 配置: Animal.java package study01_autoconfig.beanConfig; import org.spri ...

随机推荐

  1. CSS 中的 px、em、rem 和 vh

    区分 px:Pixel.像素. em:相对长度单位.继承父级元素的 font-size,值是相对于父级元素font-size的倍数. rem:Root em.相对于根元素(即 <html> ...

  2. Java之集合框架vector类设计原理

  3. Redesign Your App for iOS 7 之 页面布局【转】

    前言 iOS7是目前iOS史上最颠覆的一次改版. 它的出现令人兴奋,因为它将会带我们进入一个全新的时代: 它的到来也让我们忧心,因为它颠覆了一切,包括我们过去做过的很多努力. 但是,相信大家乐意为这个 ...

  4. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配

    一.依赖注入的三种方式      在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...

  5. 手机打车APP的机遇与挑战

    所谓打车APP,就是个能安装在手机上的打车软件.原理是通过GPS进行定位,能够搜索附近的空车信息然后反馈给用户.同样的,空车信息也会反馈给用户.一般这种啊APP都是跟地图类软件一起的.比如百度地图,谷 ...

  6. winform treeview绑定数据 DOM操作

    form1 public void treeView() { // datatable 定义变量接收 传归来的值 DataTable Father = new BuMenDA().ConSql(); ...

  7. C#构造函数用法

    1.实例构造函数 2.静态构造函数 3.私有构造函数 例: 创建一个类 using System; using System.Collections.Generic; using System.Lin ...

  8. SOA IN Real World

    微软发布了一个名为“真实世界里的面向服务架构(SOA)”的电子书.这本书表达了微软对面向服务架构的观点,并包括了数个展示如何用微软产品和技术实现SOA的真实案例.书中解释到,SOA的功能型架构本身是松 ...

  9. 老司机图文教程教你如何免费下载腾讯视频的视频mp4(直接下载到,不用qlv格式转mp4格式,亲测)

    关于如何下载到腾讯视频的mp4这个问题,大家想必经过多翻搜索,都未必找到满意的答案吧. 下载微信公众号文章中引用的腾讯视频的方法也是一样适用本方法. 因为用腾讯视电脑客户端和手机APP下载到的都是QL ...

  10. YARN 的调度选项

    YARN 中有三种调度器: 1. FIFO 调度器 (FIFO Scheduler) 应用在一个队列中,按照提交的顺序运行应用. 缺点:小作业如果在大作业后面提交,将会一直等到大作业结束才运行. 2. ...