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. [GO]全局变量

    package main import "fmt" func test01() { fmt.Println("test a = ", a) } //a := 1 ...

  2. css总结2:Flex 布局教程:Flex 语法(转)

    Flex 布局教程:语法篇 网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些 ...

  3. 三维GIS

    三维GIS数据结构 三维GIS数据库 三维渲染显示 点云处理 cnki:http://kns.cnki.net/kns/brief/default_result.aspx

  4. 【Java】java中的compareTo和compare的区别

    compare 从这里可以看出,compare是Comparator接口中的一个类,再看一下源代码中的解释 Compares its two arguments for order. Returns ...

  5. JAVA读取控制台的输入【转】

    前面介绍了使用IO类实现文件读写的示例,其实在很多地方还需要使用到IO类,这里再以读取控制台输入为例子来介绍IO类的使用. 控制台(Console)指无图形界面的程序,运行时显示或输入数据的位置,前面 ...

  6. 离线安装 python 第三方库

     离线安装 python 第三方库 首先你需要在联网的服务器上已经安装了一个第三方库,比如是paramiko,也就是说你已经执行了 pip install paramiko    ,小提示: 如果在安 ...

  7. WCF进阶(二)——Contract

    前言 我和用户有个约定,这个契约上篇已经说过了,分为服务契约.操作契约.消息契约.数据契约等,说白了,你到底让我看到什么,你告诉我,或者说,我可以让你看到什么,你敢用吗?下面就说一些基础的,关于这个些 ...

  8. 查看Eclipse版本号的方法及各个版本区别 Eclipse选择标准

    这篇文章主要介绍了查看Eclipse版本号的方法及各个版本区别 Eclipse选择标准,方便初学者选择适合自己的版本,需要的朋友可以参考下 Eclipse 是一个开放源代码的.基于Java的可扩展开发 ...

  9. linux上使用tomcat及查看日志

    启动 startup.sh #执行bin/startup.sh #启动tomcatbin/shutdown.sh #停止tomcattail -f logs/catalina.out #看tomcat ...

  10. CKEditor编辑器的使用方法

    CKEditor  网页中实现所见即所得的编辑器. 使用步骤: 1.下载CKEditor  下载地址:http://ckeditor.com/download 2.添加CKEditor的文件夹到项目中 ...